Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
hgbook.pdf
Скачиваний:
50
Добавлен:
17.03.2015
Размер:
3.15 Mб
Скачать

Поиск и исправление ваших ошибок

Например, хук на входящие изменения проверяющий, что набор изменений может быть скомпилирован, может помешать людям нечаянно «Нарушить сборку».

9.4.3. Что делать с чувствительными изменениями, как избежать

Даже тщательно запущенный проект может пострадать от печального события, такого как фиксация и неконтролируемое распространение файла, который содержит важные пароли.

Если что-то подобное произойдет с вами, и информация, которая случайно распространяется, действительно чувствительна, ваш первый шаг должен быть для смягчения последствий утечки, не пытаясь контролировать утечку самостоятельно. Если вы еще не 100% уверены, что вы знаете точно, кто мог увидеть изменения, вы должны немедленно сменить пароли, отменить кредитную карту, или найти другой способ, чтобы убедиться, что информация, с которой произошла утечка, уже бесполезна. Иными словами, предполагайте, что изменение распространится далеко и широко, и что ничего вы не можете сделать.

Можно надеяться, что нет механизмов, которые можно использовать для выяснения того, кто видел изменения и удалить изменения сразу во всем мире, но есть веские причины, почему это не представляется возможным.

Mercurial не предоставляет аудита, кто вытянул изменения из репозитория, потому что, как правило, либо возможность записи такой информации невозможна или тривиально обманывается. В многопользовательской или сетевой среде, вы должны, таким образом, весьма скептически относится к себе, если вы думаете, что вы определили все места, чувствительные ревизии могут распространится. Не забывайте, что люди могут и будут отправлять разветвления по электронной почте, имеют программное обеспечение резервного копирования данных вне офиса, переносят репозиторий на usb-брелках, и найти другие пути совершенно невинные, чтобы посрамить ваши попытки отследить каждую копию проблемных ревизий.

Mercurial также не дает способ сделать файл или набор изменений которые навсегда исчезают из истории, потому что нет возможности реализовать в своей копии удаление, кто-то может легко изменить свою копию Mercurial игнорировав такие директивы. Кроме того, даже если Mercurial обеспечит возможности, запретить вытягивание файла «отмеченного как удалённый» ревизии не будут затронуты ею, равно как и сканерам, сохраняющими образ жесткого диска или других механизмов. В самом деле, не распределенная система контроля версий может сделать чтобы данные надежно исчезли. Предоставляя иллюзию такого контроля, и могут легко дать ложное чувство безопасности, и это хуже, чем не предоставлять его вовсе.

9.5. Поиск источника ошибки

Конечно, возможность откатить изменение, которое внесло ошибку, это хорошо, но сначала нужно узнать, какой именно набор изменений, нужно откатить. Mercurial предоставляет неоценимую команду hg bisect, которая поможет вам эффективно автоматизировать этот процесс.

Идея hg bisect в том, что ревизии вводили некоторые изменения в поведении, которые можно определить с помощью некоторых простых бинарных испытаний. Вы не знаете, какая часть кода внесла изменения, но вы знаете, как проверить его на наличие ошибок. Команда hg bisect использует ваш тест для прямого поиска ревизии, которая содержит код, вызывающий ошибку.

Вот несколько сценариев, которые помогут вам понять, как можно применить эту команду.

Самая последняя версия программного обеспечения имеет ошибку, и Вы помните, что ее не было несколько недель назад, но не знаете, когда она появилась. Тут-то, ваш бинарный тест проверяет [ревизии] на наличие этой ошибки.

Вы исправили ошибку в спешке, и теперь пришло время закрыть запись об ошибке в багтрекере вашей команды. Багтрекер данных требует ID ревизии, когда вы закрываете записи, но вы не помните, в какой ревизии Вы исправили ошибку. Снова, ваш бинарный тест проверяет на наличие ошибки.

Ваше программное обеспечение работает правильно, но работает на 15% медленнее, чем в прошлый раз. Вы хотите знать, какие ревизии внесли уменьшение производительности. В этом случае ваш бинарный тест измеряет производительность вашего программного обеспечения, чтобы показать, что «быстрее» или «медленнее».

104

Поиск и исправление ваших ошибок

Размеры компонент проекта, который Вы ведете внезапно раздулись, и вы подозреваете, что что-то изменилось во время построения проекта.

Из этих примеров должно быть ясно, что команда hg bisect полезна не только для нахождения источников ошибок. С ее помощью можно найти любое «непредвиденное свойство» кодов. То, которое не удаётся найти простым текстовым поиском, но можно отловить бинарным тестом.

Введем немного терминологии, просто чтобы понять, какая часть процесса поиска ложится на Вас и какая на Mercurial. Тест это то, что выбирает ревизию, когда вы запускаете hg bisect. Проверка — это то, что hg bisect запускает чтобы сказать, какая ревизия хороша. Наконец, мы будем использовать слово «bisect», и как существительное (бисектриса) и глагол (делить пополам), во фразе «поиск с использованием команды hg bisect».

Прямолинейный способ автоматизации процесса поиска — просто проверять каждый Changeset. Однако масштабы этого ненормальны. Если тестирование одной ревизии занимает десять минут то полный просмотр 10000 ревизий в вашем хранилище, потребует в среднем 35 дней. Даже если бы вы знали, что ошибка была внесена в одной из последних 500 ревизий и ограничили поиск этим, вы по-прежнему будете искать более чем 40 часов, чтобы найти эту ревизию.

hg bisect использует свои знания «формы» истории вашего проекта и чтобы выполнить поиск по времени пропорционально логарифму числа проверяемых ревизий (вид выполняемого поиска называется дихотомический поиск). При таком подходе, поиск по 10000 ревизий займет менее трех часов, даже при десяти минутах на одно испытание (поиск потребует около 14 проверок). Ограничьте поиск последними ста ревизиями, и это займет всего около часа (примерно семь тестов).

Команде известно о «ветвистом» характере истории проекта в Mercurial, поэтому у него нет проблем, связанных с ветвлениями, слияниями, или несколькими головами в репозитории. Он может обрезать все ветви истории одной проверкой, который, как она работает так эффективно.

9.5.1. Использование команды hg bisect

Вот пример hg bisect в действии.

Примечание

В версии 0.9.5 и более ранних, hg bisect не является встроенной командой: она распространялясь с Mercurial как расширение. В этом разделе описана встроенная команды, а не старое расширение.

Теперь давайте создадим репозитарий, так что мы сможем попробовать команду hg bisect отдельно.

$ hg init mybug $ cd mybug

Мы будем моделировать проект, который содержит ошибку простым образом: создать незначительные изменения в цикле, и назначить одно конкретное изменение, которое будет иметь «ошибку». Этот цикл создает 35 ревизий, каждое добавление одного файла в хранилище. Мы представляем нашу «ошибку» с файлом, который содержит текст «У меня есть губы».

$ buggy_change=22

$ for (( i = 0; i < 35; i++ )); do

>if [[ $i = $buggy_change ]]; then

>echo 'i have a gub' > myfile$i

>hg commit -q -A -m 'buggy changeset'

>else

>echo 'nothing to see here, move along' > myfile$i

>hg commit -q -A -m 'normal changeset'

>fi

>done

Следующее, что мы хотели бы сделать, это понять, как использовать команду hg bisect. Для этого мы можем использовать встроенная справочная механизмом Mercurial.

$ hg help bisect

105

Поиск и исправление ваших ошибок

hg bisect [-gbsr] [-U] [-c CMD] [REV]

subdivision search of changesets

This command helps to find changesets which introduce problems. To use, mark the earliest changeset you know exhibits the problem as bad, then mark the latest changeset which is free from the problem as good. Bisect will update your working directory to a revision for testing (unless the -U/--noupdate option is specified). Once you have performed tests, mark the working directory as good or bad, and bisect will either update to another candidate changeset or announce that it has found the bad revision.

As a shortcut, you can also use the revision argument to mark a revision as good or bad without checking it out first.

If you supply a command, it will be used for automatic bisection. Its exit status will be used to mark revisions as good or bad: status 0 means good, 125 means to skip the revision, 127 (command not found) will abort the bisection, and any other non-zero exit status means the revision is bad.

Returns 0 on success.

options:

 

 

-r --reset

reset bisect state

-g --good

mark changeset

good

-b --bad

mark changeset

bad

-s --skip

skip testing changeset

-e --extend

extend the bisect range

-c --command CMD use command to

check changeset state

-U --noupdate

do not update to target

use "hg -v help bisect" to show more info

Команда hg bisect работает по шагам. Каждый шаг происходит следующим образом.

1.Вы запускаете Ваш бинарный тест.

Если тест успешен, Вы говорите об этом запуская команду hg bisect --good.

Если неуспешен, запускаете команду hg bisect --bad

2.Mercurial использует вашу информацию, чтобы решить, какая ревизия для тестирования следующая

3.Он обновляет рабочий каталог до этой ревизии и процесс повторяется сначала

Процесс заканчивается, когда hg bisect идентифицирует уникальный набор изменений, который знаменует собой точку, где Ваш тест перешол из «успешног» в «неуспешный».

Чтобы начать поиск, должны запустить команду hg bisect --reset.

$ hg bisect --reset

В нашем случае мы используем очень простой бинарный тест: мы проверим, содержит ли какой-то файл в хранилище строку «У меня есть жук». Если это так, эта ревизия содержит изменения, которые «вызвали ошибку». По соглашению, ревизия, которая обладает свойством «плохо», а не ту, которая не является «хорошим».

Чаще всего, ревизия с которой синхронизирован рабочий каталог (как правило, 'typ' — последняя голова), уже столкнулись с проблемой внесенной бажной правкой, поэтому мы помечаем его как «плохое».

$ hg bisect --bad

Нашей следующей задачей является назначить ревизию, про которую известно, что она не содержит искомую ошибку; Команда hg bisect ограничивает свой поиск между первой парой «хорошая — плохая» ревизиия. В нашем случае, мы знаем, что 10-я ревизия не имела ошибок. (Я расскажу несколько слов о выборе первой «хорошей» ревизии позднее).

106

Поиск и исправление ваших ошибок

$ hg bisect --good 10

Testing changeset 22:e9e43d57c12e (24 changesets remaining, ~4 tests) 0 files updated, 0 files merged, 12 files removed, 0 files unresolved

Обратите внимание, эта команда что-то выводит [на экран]

Он рассказал нам, как много ревизий он должен рассматривать прежде чем он сможет определить, где введена одна ошибка, и как много тестов, потребуется.

Он обновлил рабочий каталог до следующей ревизии для тестирования, и рассказал нам, какую ревизию будем тестировать.

Теперь запустим наш тест в рабочием каталоге. Мы используем команду grep, чтобы увидеть, находится ли наш «плохой» файл в рабочей директории. Если это так, эта ревизия является плохой, если нет — хорошей.

$ if grep -q 'i have a gub' *

>then

>result=bad

>else

>result=good

>fi

$ echo this revision is $result this revision is bad

$ hg bisect --$result

Testing changeset 16:a20d4936611f (12 changesets remaining, ~3 tests) 0 files updated, 0 files merged, 6 files removed, 0 files unresolved

Этот тест выглядит идеальным кандидатом для автоматизации, так что давайте превратим его в функцию shell.

$ mytest() {

>if grep -q 'i have a gub' *

>then

>result=bad

>else

>result=good

>fi

>echo this revision is $result

>hg bisect --$result

>}

Теперь мы можем запустить весь тест одной командой mytest.

$ mytest

this revision is good

Testing changeset 19:d018a2afc0b4 (6 changesets remaining, ~2 tests) 3 files updated, 0 files merged, 0 files removed, 0 files unresolved

Теперь мы можем запустить весь шаг тестирования с одной командой, mytest.

$ mytest

this revision is good

Testing changeset 20:850a595df5d3 (3 changesets remaining, ~1 tests) 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ mytest

this revision is good

Testing changeset 21:a3b0fef2a78f (2 changesets remaining, ~1 tests) 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ mytest

this revision is good

The first bad revision is:

changeset:

22:e9e43d57c12e

user:

Bryan

O'Sullivan <bos@serpentine.com>

date:

Thu Feb 02 14:09:26 2012 +0000

summary:

buggy

changeset

Хотя у нас было 40 ревизий для поиска, hg bisect сумел найти «ошибку» с пяти испытаний. Поскольку количество тестов, для hg bisect растет логарифмически с числом ревизий для поиска, то преимущество перед «методом грубой силы» увеличивается с каждой добавленной ревизией.

107

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]