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.50.1 → 2.51.0 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-new> --term-(good|old)=<term-old>] [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...] git bisect (bad|new|<term-new>) [<rev>] git bisect (good|old|<term-old>) [<rev>...] git bisect terms [--term-(good|old) | --term-(bad|new)] 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 help
Ця команда використовує алгоритм бінарного пошуку, щоб знайти коміт в історії вашого проєкту, який вніс помилку. Ви використовуєте його, спочатку повідомляючи їй "поганий" коміт, який, як відомо, містить помилку, і "хороший" коміт, який, як відомо, існував до появи помилки. Потім git
bisect
вибирає коміт між цими двома кінцевими точками та запитує вас, чи є вибраний коміт "хорошим" чи "поганим". Він продовжує звужувати діапазон, доки не знайде саме той коміт, який вніс зміну.
Фактично, git
bisect
можна використовувати для пошуку коміту, який змінив будь-яку властивість вашого проєкту; наприклад, коміт, який виправив помилку, або коміт, який покращив продуктивність бенчмарка. Для підтримки цього більш загального використання замість «хороший» та «поганий» можна використовувати терміни «старий» та «новий», або ви можете обрати власні терміни. Дивіться розділ «Альтернативні терміни» нижче для отримання додаткової інформації.
Основні команди бісекції: старт, погано, добре
Наприклад, припустимо, що ви намагаєтеся знайти коміт, який зламав функцію, яка, як відомо, працювала у версії v2.6.13-rc2
вашого проєкту. Ви починаєте сеанс поділу на дві частини наступним чином:
$ git bisect start $ git bisect bad # Поточна версія погана $ git bisect good v2.6.13-rc2 # v2.6.13-rc2 відома своєю непоганою версією
Після того, як ви вказали хоча б один поганий та один хороший коміт, git
bisect
вибирає коміт посередині цього діапазону історії, перевіряє його та виводить щось подібне до наступного:
Розділення: після цього залишилося протестувати 675 редакцій (приблизно 10 кроків)
Тепер вам слід скомпілювати отриману версію та протестувати її. Якщо ця версія працює правильно, введіть
$ git bisect good
Якщо ця версія пошкоджена, введіть
$ git bisect bad
Тоді git
bisect
відповість чимось на кшталт
Розділення: після цього залишилося протестувати 337 редакцій (приблизно 9 кроків)
Продовжуйте повторювати процес: скомпілюйте дерево, протестуйте його та, залежно від того, чи воно хороше, чи погане, виконайте git
bisect
good
або git
bisect
bad
, щоб запитати наступний коміт, який потребує тестування.
Зрештою, ревізій для перевірки більше не залишиться, і команда виведе опис першого поганого коміту. Посилання refs/bisect/bad
залишиться вказуючим на цей коміт.
Скидання бісекту
Після сеансу бісекції, щоб очистити стан бісекції та повернутися до початкового HEAD, виконайте таку команду:
$ git bisect reset
За замовчуванням, це поверне ваше дерево до коміту, який було отримано перед git
bisect
start
. (Новий git
bisect
start
також зробить це, оскільки він очищає старий стан бісекції.)
За допомогою необов’язкового аргументу ви можете повернутися до іншого коміту:
$ git bisect reset <commit>
Наприклад, git
bisect
reset
bisect/bad
перевірить першу погану ревізію, тоді як git
bisect
reset
HEAD
залишить вас на поточному коміті bisection та взагалі уникне перемикання комітів.
Альтернативні терміни
Іноді ви шукаєте не коміт, який призвів до поломки, а радше коміт, який спричинив зміну між якимось іншим "старим" станом та "новим". Наприклад, ви можете шукати коміт, який призвів до певного виправлення. Або ви можете шукати перший коміт, у якому назви файлів вихідного коду нарешті були конвертовані відповідно до стандарту іменування вашої компанії. Або щось інше.
У таких випадках може бути дуже заплутано використовувати терміни «хороший» та «поганий» для позначення «стану до змін» та «стану після змін». Тому замість «хороший» та «поганий» можна використовувати терміни відповідно «старий» та «новий». (Але зверніть увагу, що не можна змішувати «хороший» та «поганий» зі «старим» та «новим» в одному сеансі.)
У цьому більш загальному випадку, ви надаєте git
bisect
"новий" коміт, який має певну властивість, та "старий" коміт, який не має цієї властивості. Щоразу, коли git
bisect
перевіряє коміт, ви перевіряєте, чи має цей коміт цю властивість. Якщо так, позначте коміт як "новий"; інакше позначте його як "старий". Після завершення розбиття, git
bisect
повідомить, який коміт ввів цю властивість.
Щоб використовувати "old" та "new" замість "good" та "bad", потрібно виконати git
bisect
start
без комітів як аргументу, а потім виконати такі команди для додавання комітів:
git bisect old [<rev>]
щоб вказати, що коміт було здійснено до бажаної зміни, або
git bisect new [<rev>...]
щоб вказати, що це було після.
Щоб отримати нагадування про терміни, що використовуються на даний момент, скористайтеся
git bisect terms
Ви можете отримати лише старий термін за допомогою git
bisect
terms
--term-old
або git
bisect
terms
--term-good
; git
bisect
terms
--term-new
та git
bisect
terms
--term-bad
можна використовувати, щоб дізнатися, як викликати коміти, новіші за шукану зміну.
Якщо ви хочете використовувати власні терміни замість "поганий"/"добрий" або "новий"/"старий", ви можете вибрати будь-які назви (окрім існуючих підкоманд бісекції, таких як reset
, start
тощо), розпочавши бісекцію за допомогою
git bisect start --term-old <term-old> --term-new <term-new>
Наприклад, якщо ви шукаєте коміт, який запровадив регресію продуктивності, ви можете використовувати
git bisect start --term-old fast --term-new slow
Або якщо ви шукаєте коміт, який виправив помилку, ви можете використовувати
git bisect start --term-new fixed --term-old broken
Потім використовуйте git
bisect
<term-old> та git
bisect
<term-new> замість git
bisect
good
та git
bisect
bad
для позначення комітів.
Розділити візуалізацію/перегляд
Щоб побачити підозрюваних, що залишилися в 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
Розділити журнал та розділити повтор
Після позначення редакцій як хороших або поганих, виконайте таку команду, щоб показати, що було зроблено на даний момент:
$ git bisect log
Якщо ви виявите, що помилилися, вказавши статус редакції, ви можете зберегти вивід цієї команди у файлі, відредагувати його, щоб видалити неправильні записи, а потім виконати такі команди, щоб повернутися до виправленого стану:
$ git bisect reset $ git bisect replay that-file
Уникнення тестування коміту
Якщо посеред сеансу bisect ви знаєте, що запропонована ревізія не є гарною для тестування (наприклад, вона не збирається, і ви знаєте, що збій не має нічого спільного з помилкою, яку ви шукаєте), ви можете вручну вибрати сусідній коміт і протестувати його.
Наприклад:
$ git bisect good/bad # попередній раунд був хорошим чи поганим. Розділення: після цього залишилося протестувати 337 редакцій (приблизно 9 кроків) $ git bisect visualize # ой, це нецікаво. $ git reset --hard HEAD~3 # спробуйте 3 ревізії перед чим # було запропоновано
Потім скомпілюйте та протестуйте вибрану ревізію, а потім позначте її як хорошу або погану звичайним способом.
Розділити корабель навпіл
Замість того, щоб самостійно вибирати найближчий коміт, ви можете попросити 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
(включно) слід пропустити.
Зменшення бісекції шляхом надання більшої кількості параметрів для початку бісекції
Ви можете ще більше скоротити кількість спроб, якщо знаєте, яка частина дерева пов’язана з проблемою, яку ви відстежуєте, вказавши параметри pathspec під час виконання команди 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 is bad # v2.6.20-rc4 and v2.6.20-rc1 are good
Розріз на дві частини
Якщо у вас є скрипт, який може визначити, чи поточний вихідний код хороший чи поганий, ви можете розділити його навпіл, виконавши команду:
$ git bisect run my_script arguments
Зверніть увагу, що скрипт (my_script
у наведеному вище прикладі) повинен завершитися з кодом 0, якщо поточний вихідний код хороший/старий, і завершитися з кодом від 1 до 127 (включно), крім 125, якщо поточний вихідний код поганий/новий.
Будь-який інший код виходу перерве процес поділу на дві частини. Слід зазначити, що програма, яка завершується через exit
(-1
), залишає $? = 255 (див. сторінку довідки exit(3)), оскільки значення обрізається за допомогою & 0377.
Спеціальний код виходу 125 слід використовувати, коли поточний вихідний код неможливо перевірити. Якщо скрипт завершується з цим кодом, поточну ревізію буде пропущено (див. git
bisect
skip
вище). 125 було обрано як найвище розумне значення для цієї мети, оскільки 126 та 127 використовуються оболонками POSIX для сигналізації про певний стан помилки (127 означає команду не знайдено, 126 означає команду знайдено, але не виконувану – ці деталі не мають значення, оскільки вони є звичайними помилками у скрипті, якщо говорити про bisect
run
).
Часто ви можете зіткнутися з ситуацією, коли під час сеансу бісекції вам потрібно внести тимчасові зміни (наприклад, s/#define DEBUG 0/#define DEBUG 1/ у заголовковий файл або «версія, яка не має цього коміту, потребує цього патчу, щоб вирішити іншу проблему, яка не цікавить цю бісекцію»), застосовані до тестованої версії.
Щоб впоратися з такою ситуацією, після того, як внутрішній «git bisect» знайде наступну ревізію для тестування, скрипт може застосувати патч перед компіляцією, запустити справжній тест, а потім вирішити, чи пройшла ревізія (можливо, з необхідним патчем) тест, а потім перемотати дерево до початкового стану. Нарешті, скрипт повинен завершитися зі статусом справжнього тесту, щоб цикл команди git
bisect
run
визначив кінцевий результат сеансу bisect.
ОПЦІЇ
- --no-checkout
-
Не перевіряйте нове робоче дерево на кожній ітерації процесу поділу на дві частини. Натомість просто оновіть посилання з назвою
BISECT_HEAD
, щоб воно вказувало на коміт, який слід перевірити.Цей параметр може бути корисним, коли тест, який ви виконували б на кожному кроці, не вимагає перевіреного дерева.
Якщо репозиторій пустий, передбачається
--no-checkout
. - --first-parent
-
Слідкуйте лише за першим батьківським комітом після виявлення коміту злиття.
При виявленні регресій, що виникли внаслідок злиття гілки, коміт злиття буде ідентифіковано як впровадження помилки, а його предки будуть проігноровані.
Ця опція особливо корисна для уникнення хибних спрацьовувань, коли об’єднана гілка містила пошкоджені або непридатні для збірки коміти, але саме злиття пройшло нормально.
ПРИКЛАДИ
-
Автоматично розділити пошкоджену збірку між версіями 1.2 та HEAD:
$ git bisect start HEAD v1.2 -- # HEAD поганий, v1.2 хороший $ git bisect run make # "make" створює застосунок $ git bisect reset # вийти з сеансу бісекти
-
Автоматично розділити невдачу тесту між початком та HEAD:
$ git bisect start HEAD origin -- # HEAD поганий, origin хороший $ git bisect run make test # "збірки та тести" $ git bisect reset # вийти з сеансу бісекти
-
Автоматично розділити пошкоджений тестовий випадок навпіл:
$ 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 # вийти з сеансу бісекти
Тут ми використовуємо користувацький скрипт
test.sh
. У цьому скрипті, якщоmake
не вдається, ми пропускаємо поточний коміт.check_test_case.sh
повинен мати значенняexit
0
, якщо тестовий випадок пройде успішно, іexit
1
в іншому випадку.Безпечніше, якщо і
test.sh
, іcheck_test_case.sh
знаходяться поза репозиторієм, щоб запобігти взаємодії між процесами bisect, make та test і скриптами. -
Автоматичне розділення навпіл з тимчасовими змінами (виправлення):
$ cat ~/test.sh #!/bin/sh # налаштувати робоче дерево, об'єднавши гілку з виправленнями # а потім спробуйте побудувати if git merge --no-commit --no-ff hot-fix && make then # запустити тест для конкретного проекту та повідомити про його стан ~/check_test_case.sh status=$? else # повідомте абоненту, що це неможливо перевірити status=125 fi # скасувати налаштування, щоб дозволити чистий перехід до наступного коміту git reset --hard # повернення контролю exit $status
Це застосовує модифікації з гілки hot-fix перед кожним тестовим запуском, наприклад, у випадку, якщо ваше середовище збірки або тестування змінилося таким чином, що старіші ревізії можуть потребувати виправлення, яке новіші вже потребують. (Переконайтеся, що гілка hot-fix базується на коміті, який міститься у всіх ревізіях, які ви розділяєте, щоб злиття не втягувало забагато змін, або використовуйте
git
cherry-pick
замістьgit
merge
.) -
Автоматично розділити пошкоджений тестовий випадок навпіл:
$ git bisect start HEAD HEAD~10 -- # винуватець серед останніх 10 $ git bisect run sh -c "make || exit 125; ~/check_test_case.sh" $ git bisect reset # вийти з сеансу бісекти
Це показує, що можна обійтися без сценарію запуску, якщо написати тест в одному рядку.
-
Знайдіть вдалу область графа об’єктів у пошкодженому репозиторії
$ git bisect start HEAD <known-good-commit> [ <boundary-commit> ... ] --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 # вийти з сеансу бісекти
У цьому випадку, коли «git bisect run» завершиться, bisect/bad посилатиметься на коміт, який має принаймні одного батьківського елемента, граф досяжності якого є повністю прохідним у сенсі, що вимагається «об’єктами git pack».
-
Шукайте виправлення замість регресії в коді
$ 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]