Setup and Config
Getting and Creating Projects
Basic Snapshotting
Branching and Merging
Sharing and Updating Projects
Inspection and Comparison
Patching
Debugging
External Systems
Server Admin
Guides
- gitattributes
- Command-line interface conventions
- Everyday Git
- Frequently Asked Questions (FAQ)
- Glossary
- Hooks
- gitignore
- gitmodules
- Revisions
- Submodules
- Tutorial
- Workflows
- All guides...
Administration
Plumbing Commands
- 2.53.0 → 2.54.0 no changes
-
2.52.0
2025-11-17
- 2.50.1 → 2.51.2 no changes
-
2.50.0
2025-06-16
- 2.44.1 → 2.49.1 no changes
-
2.44.0
2024-02-23
- 2.43.3 → 2.43.7 no changes
-
2.43.2
2024-02-13
-
2.43.1
2024-02-09
-
2.43.0
2023-11-20
- 2.42.1 → 2.42.4 no changes
-
2.42.0
2023-08-21
- 2.29.1 → 2.41.3 no changes
-
2.29.0
2020-10-19
- 2.25.1 → 2.28.1 no changes
-
2.25.0
2020-01-13
- 2.18.1 → 2.24.4 no changes
-
2.18.0
2018-06-21
- 2.17.0 → 2.17.6 no changes
-
2.16.6
2019-12-06
- 2.14.6 → 2.15.4 no changes
-
2.13.7
2018-05-22
- 2.12.5 no changes
-
2.11.4
2017-09-22
- 2.10.5 no changes
-
2.9.5
2017-07-30
- 2.8.6 no changes
-
2.7.6
2017-07-30
-
2.6.7
2017-05-05
- 2.2.3 → 2.5.6 no changes
-
2.1.4
2014-12-17
-
2.0.5
2014-12-17
ОБЗОР
git bisect start [--term-(bad|new)=<термин-новый> --term-(good|old)=<термин-старый>]
[--no-checkout] [--first-parent] [<плохой> [<хороший>…]] [--] [<спецификатор-пути>…]
git bisect (bad|new|<термин-новый>) [<ред>]
git bisect (good|old|<термин-старый>) [<ред>…]
git bisect terms [--term-(good|old) | --term-(bad|new)]
git bisect skip [(<ред>|<диапазон>)…]
git bisect next
git bisect reset [<коммит>]
git bisect (visualize|view)
git bisect replay <файл-журнала>
git bisect log
git bisect run <команда> [<аргумент>…]
git bisect help
ОПИСАНИЕ
Эта команда использует алгоритм двоичного поиска, чтобы найти, какой коммит в истории вашего проекта внёс ошибку. Вы используете её, сначала указав "плохой" коммит, который, как известно, содержит ошибку, и "хороший" коммит, который, как известно, был до того, как ошибка была внесена. Затем git bisect выбирает коммит между этими двумя конечными точками и спрашивает вас, является ли выбранный коммит "хорошим" или "плохим". Он продолжает сужать диапазон, пока не найдёт точный коммит, который внёс изменение.
На самом деле git bisect можно использовать для поиска коммита, который изменил любое свойство вашего проекта; например, коммит, который исправил ошибку, или коммит, который улучшил производительность теста. Для поддержки этого более общего использования термины "старый" и "новый" можно использовать вместо "хороший" и "плохой", или вы можете выбрать свои собственные термины. Дополнительную информацию см. в разделе "Альтернативные термины" ниже.
Основные команды bisect: start, bad, good
В качестве примера предположим, что вы пытаетесь найти коммит, который сломал функцию, заведомо работавшую в версии v2.6.13-rc2 вашего проекта. Вы начинаете сеанс bisect следующим образом:
$ git bisect start $ git bisect bad # Текущая версия плохая $ git bisect good v2.6.13-rc2 # v2.6.13-rc2 заведомо хорошая
Как только вы указали по крайней мере один плохой и один хороший коммит, git bisect выбирает коммит в середине этого диапазона истории, переключает его и выводит что-то похожее на следующее:
Bisecting: 675 редакций осталось протестировать после этого (примерно 10 шагов)
Теперь вы должны скомпилировать переключённую версию и протестировать её. Если эта версия работает правильно, введите
$ git bisect good
Если эта версия сломана, введите
$ git bisect bad
Затем git bisect ответит чем-то вроде
Bisecting: 337 редакций осталось протестировать после этого (примерно 9 шагов)
Продолжайте повторять процесс: компилируйте дерево, тестируйте его и, в зависимости от того, хорош он или плох, запускайте git bisect good или git bisect bad, чтобы запросить следующий коммит, который необходимо протестировать.
В конце концов не останется больше редакций для проверки, и команда выведет описание первого плохого коммита. Ссылка refs/bisect/bad останется указывать на этот коммит.
Сброс bisect
После сеанса bisect, чтобы очистить состояние бинарного поиска и вернуться к исходному HEAD, выполните следующую команду:
$ git bisect reset
По умолчанию это вернёт ваше дерево к коммиту, который был переключён до git bisect start. (Новый git bisect start также сделает это, поскольку он очищает старое состояние бинарного поиска.)
С необязательным аргументом вы можете вернуться к другому коммиту:
$ git bisect reset <коммит>
Например, git bisect reset bisect/bad переключит первую плохую редакцию, в то время как git bisect reset HEAD оставит вас на текущем коммите бинарного поиска и вообще избежит переключения коммитов.
Альтернативные термины
Иногда вы ищете не коммит, который внёс поломку, а коммит, который вызвал изменение между некоторым другим "старым" состоянием и "новым" состоянием. Например, вы можете искать коммит, который внёс определённое исправление. Или вы можете искать первый коммит, в котором имена файлов исходного кода были наконец преобразованы в стандарт именования вашей компании. Или что-то ещё.
В таких случаях может быть очень запутанным использование терминов "хороший" и "плохой" для обозначения "состояния до изменения" и "состояния после изменения". Поэтому вместо этого вы можете использовать термины "старый" и "новый" соответственно вместо "хороший" и "плохой". (Но обратите внимание, что вы не можете смешивать "хороший" и "плохой" со "старым" и "новым" в одном сеансе.)
В этом более общем использовании вы предоставляете git bisect "новый" коммит, который имеет некоторое свойство, и "старый" коммит, который не имеет этого свойства. Каждый раз, когда git bisect переключает коммит, вы проверяете, имеет ли этот коммит это свойство. Если имеет, пометьте коммит как "новый"; в противном случае пометьте его как "старый". Когда бинарный поиск завершён, git bisect сообщит, какой коммит ввёл это свойство.
Чтобы использовать "старый" и "новый" вместо "хороший" и "плохой", вы должны запустить git bisect start без коммитов в качестве аргумента, а затем выполнить следующие команды для добавления коммитов:
git bisect old [<ред>]
чтобы указать, что коммит был до искомого изменения, или
git bisect new [<ред>...]
чтобы указать, что он был после.
Чтобы получить напоминание о текущих используемых терминах, используйте
git bisect terms
Вы можете получить только старый термин с помощью git bisect terms --term-old или git bisect terms --term-good; git bisect terms --term-new и git bisect terms --term-bad можно использовать, чтобы узнать, как называть коммиты, более новые, чем искомое изменение.
Если вы хотите использовать свои собственные термины вместо "плохой"/"хороший" или "новый"/"старый", вы можете выбрать любые имена, которые вам нравятся (кроме существующих подкоманд bisect, таких как reset, start, …), начав бинарный поиск с помощью
git bisect start --term-old <термин-старый> --term-new <термин-новый>
Например, если вы ищете коммит, который внёс регрессию производительности, вы можете использовать
git bisect start --term-old fast --term-new slow
Или если вы ищете коммит, который исправил ошибку, вы можете использовать
git bisect start --term-new fixed --term-old broken
Затем используйте git bisect <термин-старый> и git bisect <термин-новый> вместо git bisect good и git bisect bad для пометки коммитов.
Визуализация/просмотр bisect
Чтобы увидеть текущие оставшиеся подозреваемые коммиты в gitk, выполните следующую команду во время процесса бинарного поиска (подкоманда view может использоваться как альтернатива visualize):
$ git bisect visualize
Git обнаруживает графическую среду через различные переменные среды: DISPLAY, которая устанавливается в средах X Window System в Unix-системах. SESSIONNAME, которая устанавливается в Cygwin в интерактивных сеансах рабочего стола. MSYSTEM, которая устанавливается в Msys2 и Git для Windows. SECURITYSESSIONID, которая может быть установлена в macOS в интерактивных сеансах рабочего стола.
Если ни одна из этих переменных среды не установлена, вместо этого используется git log. Вы также можете указывать параметры командной строки, такие как -p и --stat.
$ git bisect visualize --stat
Журнал bisect и воспроизведение bisect
После пометки редакций как хороших или плохих выполните следующую команду, чтобы показать, что было сделано на данный момент:
$ git bisect log
Если вы обнаружите, что ошиблись в указании статуса редакции, вы можете сохранить вывод этой команды в файл, отредактировать его, чтобы удалить неправильные записи, а затем выполнить следующие команды, чтобы вернуться в исправленное состояние:
$ git bisect reset $ git bisect replay тот-файл
Избегание тестирования коммита
Если в середине сеанса bisect вы знаете, что предложенная редакция не подходит для тестирования (например, она не собирается, и вы знаете, что ошибка сборки не связана с ошибкой, которую вы ищете), вы можете вручную выбрать ближайший коммит и протестировать его вместо этого.
Например:
$ git bisect good/bad # предыдущий раунд был хорошим или плохим. Bisecting: 337 редакций осталось протестировать после этого (примерно 9 шагов) $ git bisect visualize # ой, это неинтересно. $ git reset --hard HEAD~3 # попробовать 3 редакции до того, # что было предложено
Затем скомпилируйте и протестируйте выбранную редакцию, а после этого пометьте редакцию как хорошую или плохую обычным способом.
Пропуск в bisect
Вместо того чтобы выбирать ближайший коммит самостоятельно, вы можете попросить Git сделать это за вас, выполнив команду:
$ git bisect skip # Текущую версию нельзя протестировать
Однако, если вы пропустите коммит, соседний с тем, который вы ищете, Git не сможет точно определить, какой из этих коммитов был первым плохим.
Вы также можете пропустить диапазон коммитов, а не только один коммит, используя обозначение диапазона. Например:
$ git bisect skip v2.5..v2.6
Это указывает процессу bisect, что ни один коммит после v2.5, вплоть до v2.6 включительно, не должен тестироваться.
Обратите внимание, что если вы также хотите пропустить первый коммит диапазона, вы должны выполнить команду:
$ git bisect skip v2.5 v2.5..v2.6
Это указывает процессу bisect, что коммиты между v2.5 и v2.6 (включительно) должны быть пропущены.
Следующий в bisect
Обычно после пометки редакции как хорошей или плохой Git автоматически вычисляет и переключает следующую редакцию для тестирования. Однако, если вам нужно явно запросить следующий шаг бинарного поиска, вы можете использовать:
$ git bisect next
Вы можете использовать это, чтобы возобновить процесс бинарного поиска после его прерывания путём переключения другой редакции.
Сокращение бинарного поиска путём передачи большего количества параметров в bisect start
Вы можете дополнительно сократить количество попыток, если знаете, какая часть дерева связана с проблемой, которую вы отслеживаете, указав параметры спецификатора пути при выполнении команды bisect start:
$ git bisect start -- arch/i386 include/asm-i386
Если вы заранее знаете более одного хорошего коммита, вы можете сузить пространство бинарного поиска, указав все хорошие коммиты сразу после плохого коммита при выполнении команды bisect start:
$ git bisect start v2.6.20-rc6 v2.6.20-rc4 v2.6.20-rc1 --
# v2.6.20-rc6 плохой
# v2.6.20-rc4 и v2.6.20-rc1 хорошие
Запуск bisect
Если у вас есть сценарий, который может определить, является ли текущий исходный код хорошим или плохим, вы можете выполнить бинарный поиск, выполнив команду:
$ git bisect run мой_сценарий аргументы
Обратите внимание, что сценарий (мой_сценарий в приведённом выше примере) должен завершаться с кодом 0, если текущий исходный код хороший/старый, и завершаться с кодом от 1 до 127 (включительно), кроме 125, если текущий исходный код плохой/новый.
Любой другой код выхода прервёт процесс бинарного поиска. Следует отметить, что программа, завершающаяся через exit(-1), оставляет $? = 255 (см. страницу руководства exit(3)), поскольку значение усекается с помощью & 0377.
Специальный код выхода 125 следует использовать, когда текущий исходный код не может быть протестирован. Если сценарий завершается с этим кодом, текущая редакция будет пропущена (см. git bisect skip выше). 125 был выбран как наибольшее разумное значение для использования в этой цели, поскольку 126 и 127 используются оболочками POSIX для обозначения определённых ошибок (127 — команда не найдена, 126 — команда найдена, но не исполняема — эти детали не имеют значения, поскольку они являются обычными ошибками в сценарии, насколько это касается bisect run).
Вы часто можете обнаружить, что во время сеанса bisect вы хотите применить временные изменения (например, s/#define DEBUG 0/#define DEBUG 1/ в заголовочном файле или "редакция, которая не имеет этого коммита, требует применения этого патча для обхода другой проблемы, которая не интересует этот бинарный поиск") к тестируемой редакции.
Чтобы справиться с такой ситуацией, после того как внутренний git bisect находит следующую редакцию для тестирования, сценарий может применить патч перед компиляцией, запустить реальный тест, а затем решить, прошла ли редакция (возможно, с необходимым патчем) тест, и затем откатить дерево в исходное состояние. Наконец, сценарий должен завершиться со статусом реального теста, чтобы цикл команды git bisect run определил окончательный результат сеанса bisect.
ПАРАМЕТРЫ
- --no-checkout
-
Не переключать новый рабочий каталог на каждой итерации процесса бинарного поиска. Вместо этого просто обновить ссылку с именем
BISECT_HEAD, чтобы она указывала на коммит, который должен быть протестирован.Этот параметр может быть полезен, когда тест, который вы выполняете на каждом шагу, не требует переключённого дерева.
Если репозиторий голый, предполагается
--no-checkout. - --first-parent
-
Следовать только за первым родительским коммитом при обнаружении коммита слияния.
При обнаружении регрессий, внесённых через слияние ветки, коммит слияния будет идентифицирован как внесение ошибки, а его предки будут проигнорированы.
Этот параметр особенно полезен для избежания ложных срабатываний, когда слитая ветка содержала сломанные или некомпилируемые коммиты, но само слияние было в порядке.
ПРИМЕРЫ
-
Автоматически выполнить бинарный поиск сломанной сборки между v1.2 и HEAD:
$ git bisect start HEAD v1.2 -- # HEAD плохой, v1.2 хороший $ git bisect run make # "make" собирает приложение $ git bisect reset # выход из сеанса bisect
-
Автоматически выполнить бинарный поиск сбоя теста между origin и HEAD:
$ git bisect start HEAD origin -- # HEAD плохой, origin хороший $ git bisect run make test # "make test" собирает и тестирует $ git bisect reset # выход из сеанса bisect
-
Автоматически выполнить бинарный поиск сломанного тестового примера:
$ cat ~/test.sh #!/bin/sh make || exit 125 # это пропускает сломанные сборки ~/check_test_case.sh # проходит ли тестовый пример? $ git bisect start HEAD HEAD~10 -- # виновник среди последних 10 $ git bisect run ~/test.sh $ git bisect reset # выход из сеанса bisect
Здесь мы используем пользовательский сценарий
test.sh. В этом сценарии, еслиmakeзавершается ошибкой, мы пропускаем текущий коммит.check_test_case.shдолжен завершаться сexit0, если тестовый пример проходит, иexit1в противном случае.Будет безопаснее, если и
test.sh, иcheck_test_case.shнаходятся за пределами репозитория, чтобы предотвратить взаимодействие между процессами bisect, make и test и сценариями. -
Автоматический бинарный поиск с временными изменениями (горячее исправление):
$ cat ~/test.sh #!/bin/sh # изменить рабочий каталог, слив ветку hot-fix # и затем попытаться выполнить сборку if git merge --no-commit --no-ff hot-fix && make then # запустить специфичный для проекта тест и сообщить его статус ~/check_test_case.sh статус=$? else # сообщить вызывающему, что это не тестируется статус=125 fi # отменить изменение, чтобы разрешить чистый переход к следующему коммиту git reset --hard # вернуть управление exit $status
Это применяет изменения из ветки горячего исправления перед каждым запуском теста, например, в случае, если ваша среда сборки или тестирования изменилась, так что более старые редакции могут нуждаться в исправлении, которое у новых уже есть. (Убедитесь, что ветка горячего исправления основана на коммите, который содержится во всех редакциях, которые вы ищете, чтобы слияние не втягивало слишком много, или используйте
gitcherry-pickвместоgitmerge.) -
Автоматически выполнить бинарный поиск сломанного тестового примера:
$ git bisect start HEAD HEAD~10 -- # виновник среди последних 10 $ git bisect run sh -c "make || exit 125; ~/check_test_case.sh" $ git bisect reset # выход из сеанса bisect
Это показывает, что вы можете обойтись без сценария run, если напишете тест в одной строке.
-
Локализовать хорошую область графа объектов в повреждённом репозитории
$ git bisect start HEAD <заведомо-хороший-коммит> [ <граничный-коммит> ... ] --no-checkout $ git bisect run sh -c ' GOOD=$(git for-each-ref "--format=%(objectname)" refs/bisect/good-*) && git rev-list --objects BISECT_HEAD --not $GOOD >tmp.$$ && git pack-objects --stdout >/dev/null <tmp.$$ rc=$? rm -f tmp.$$ test $rc = 0' $ git bisect reset # выход из сеанса bisect
В этом случае, когда git bisect run завершается, bisect/bad будет ссылаться на коммит, который имеет по крайней мере одного родителя, чей достижимый граф полностью обходим в смысле, требуемом git pack objects.
-
Искать исправление вместо регрессии в коде
$ git bisect start $ git bisect new HEAD # текущий коммит помечен как новый $ git bisect old HEAD~10 # десятый коммит от текущего помечен как старый
или:
$ git bisect start --term-old broken --term-new fixed $ git bisect fixed $ git bisect broken HEAD~10
GIT
Является частью пакета git[1]