linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Главы
  • How it works
  • Уроки
  • База знаний
  • Собеседование
home/git/lessons/git-lab-10-1-bisect

lesson ── git-labs ── ~18 мин ── 7 шагов

git bisect: найти баг бинарным поиском

Цель - найти конкретный коммит, который сломал поведение, не просматривая всю историю руками. git bisect делает бинарный поиск: ты говоришь «здесь работало», «здесь сломано», Git делит интервал пополам, ты тестируешь, повторяешь. log(n) шагов вместо n.

▶ интерактивный sandbox

Поднимется контейнер gitlab/git-base с git, bash, pre-commit. В браузере откроется терминал, можно сразу git init. Каждый шаг проверяется автоматически. Сеть air-gapped, github.com недоступен.

запустить sandbox →

stack ── git · bash · 256 MB RAM · air-gapped · самоуничтожается через 30 мин простоя

Шаги

  1. 01

    Создай репо с 10 коммитами, один из которых ломает поведение

    bash
    cd /home/student/work
    mkdir -p bisect-lab && cd bisect-lab
    git init -b main
    cat > app.sh <<'EOF'
    #!/bin/bash
    echo "ok"
    EOF
    chmod +x app.sh
    git add . && git commit -m "init: working app"
    for i in 1 2 3 4; do
      echo "# noop change $i" >> app.sh   # шумовые коммиты до сломанного
      git commit -am "tweak $i"
    done
    # сломанный коммит - меняем вывод "ok" на "fail" через sed -i (in-place)
    sed -i 's/echo "ok"/echo "fail"/' app.sh
    git commit -am "refactor: tune output"
    for i in 5 6 7 8 9; do
      echo "# more noop $i" >> app.sh     # шумовые коммиты после сломанного
      git commit -am "tweak $i (later)"
    done
    git log --oneline | wc -l     # должно вывести 10

    10 коммитов. Один из них сломал вывод. Какой - сейчас неизвестно.

    ✓ 10 коммитов, текущий вывод 'fail'. Нужно найти, какой коммит виноват.

  2. 02

    Подтверди, что HEAD сломан, а первый коммит работает

    bash
    cd /home/student/work/bisect-lab
    ./app.sh                      # текущий вывод: fail
    git stash 2>/dev/null         # на всякий случай отложить локальные правки
    # --max-parents=0 = коммит без parent'а, корневой (init)
    FIRST=$(git rev-list --max-parents=0 HEAD)
    git checkout $FIRST -- app.sh # достать app.sh из init-коммита в working tree
    ./app.sh                      # вывод "ok" - подтверждение, что init работал
    git checkout HEAD -- app.sh   # вернуть текущую (сломанную) версию

    Первый коммит даёт ok. HEAD даёт fail. Поиск стартует на интервале «между ними».

    ✓ HEAD сломан, init работает. Запускай bisect.

  3. 03

    Начни bisect руками

    bash
    cd /home/student/work/bisect-lab
    git bisect start              # включаем режим поиска
    git bisect bad HEAD           # текущий коммит сломан
    FIRST=$(git rev-list --max-parents=0 HEAD)
    git bisect good $FIRST        # корневой коммит работал

    Git перепрыгнет на середину интервала и скажет что-то вроде Bisecting: 4 revisions left to test after this (roughly 2 steps). Это и есть бинарный поиск в действии.

    ✓ Bisect запущен. Git выбрал коммит посередине.

  4. 04

    Сделай один шаг bisect руками

    Проверь текущий коммит:

    bash
    cd /home/student/work/bisect-lab
    ./app.sh

    Если видишь ok - текущий коммит хороший: git bisect good. Если fail - плохой: git bisect bad. Делай по результату:

    bash
    # grep -q = тихий (только exit-код); ok найден - good, нет - bad
    ./app.sh | grep -q ok && git bisect good || git bisect bad

    Git выберет следующий коммит для проверки.

    ✓ Сделал один шаг. Интервал сократился вдвое.

  5. 05

    Заверши bisect до победы (или прерви)

    Можешь продолжить руками (./app.sh && git bisect good/bad несколько раз), но проще - перейти на автоматический поиск через bisect run. Сначала выйди из текущего:

    bash
    cd /home/student/work/bisect-lab
    git bisect reset

    Это вернёт HEAD в main.

    ✓ Bisect остановлен. Дальше - автомат.

  6. 06

    Напиши тест-скрипт для автопоиска

    git bisect run ждёт скрипт, который возвращает 0 для хорошего коммита, 1 - для плохого.

    bash
    cd /home/student/work/bisect-lab
    # тест: exit 0 если в выводе есть "ok", exit 1 если нет
    cat > test.sh <<'EOF'
    #!/bin/bash
    ./app.sh | grep -q ok
    EOF
    chmod +x test.sh
    ./test.sh && echo "exit 0 (good)" || echo "exit 1 (bad)"

    На HEAD выйдет exit 1 (bad). Это ожидаемо.

    ✓ Тест-скрипт работает. Запускай автоматический поиск.

  7. 07

    Запусти автоматический поиск через bisect run

    bash
    cd /home/student/work/bisect-lab
    # bisect start <bad> <good> - сразу задаём границы
    git bisect start HEAD $(git rev-list --max-parents=0 HEAD)
    git bisect run ./test.sh      # автопрогон: на каждом шаге запускает test.sh

    Git перепрыгнет несколько коммитов, для каждого запустит test.sh, и сообщит: <sha> is the first bad commit. Сообщение коммита должно быть refactor: tune output - тот самый, где мы заменили ok на fail.

    Выйди из bisect:

    bash
    git bisect reset

    ✓ Автоматический bisect нашёл виновного. log(n) против n.

Что ты узнал

bisect делит интервал коммитов пополам, ты отмечаешь хорошие и плохие. Когда умеешь автоматически проверять - bisect run делает всё сам.

команды

  • git bisect startначать поиск
  • git bisect badтекущий коммит плохой
  • git bisect good <sha>указать хорошую базу
  • git bisect run ./test.shавтопоиск через скрипт
  • git bisect resetвыйти из режима поиска

концепции

  • · bisect - бинарный поиск по истории
  • · критерий нужно уметь автоматизировать - script с exit-кодом
  • · exit 0 = good, exit 1 = bad, exit 125 = skip

← предыдущая

Отмена: reset, revert, reflog

следующая →

Trunk-based: фичи под флагами в main

Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки