Как я мог использовать git bisect, чтобы найти первую ХОРОШУЮ фиксацию?


94

У меня следующая проблема:

  • версия masterработает нормально
  • версия последнего тега перед master(скажем last) содержит ошибку
  • коллеге нужен патч для его lastревизии для этой определенной ошибки

Ладно. Давайте спросим у нашего друга git bisectревизию, в которой исправлена ​​ошибка:

git bisect start
git bisect bad last
git bisect good master

Но это не сработает:

Некоторые хорошие обороты не являются предшественниками плохих оборотов.
git bisect в этом случае не может работать должным образом.
Может быть, вы перепутали хорошие и плохие обороты?

Какие-нибудь подсказки, чтобы преодолеть это? Я что-то пропустил в документации?


1
Я бегу git bisect run ...автоматизировать Рассекайте. Так что у меня нет возможности просто поменять местами слова goodи bad(это было слишком очевидно). Как с помощью runнайти первую хорошую ревизию?
Daniel Böhmer

@ DanielBöhmer: вам нужно поменять местами условия внутри вашего запущенного скрипта , не так ли?
eckes

Скрипт, выполняемый пользователем, git bisect runвозвращает хороший или плохой код выхода, а не строку. Смотрите мой ответ, который я только что опубликовал ниже.
Daniel Böhmer

@ DanielBöhmer: в таком случае вам придется инвертировать код возврата, не так ли?
eckes

Правильно, это то, что описано в моем ответе.
Daniel Böhmer

Ответы:


100

Начиная с git 2.7, вы можете использовать аргументы --term-old и --term-new.

Например, вы можете определить фиксацию исправления проблемы следующим образом:

git bisect start --term-new=fixed --term-old=unfixed
git bisect fixed master
git bisect unfixed $some-old-sha1

По мере того, как будете тестировать, скажите git bisect fixedили, git bisect unfixedкак нужно .

Старый ответ для версий git до 2.7

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

В ~/.gitconfigдобавить следующее:

[alias]
        bisect-fixed = bisect bad
        bisect-unfixed = bisect good

Вы можете начать определение фиксации исправления проблемы следующим образом:

$ git bisect start
$ git bisect-fixed master
$ git bisect-unfixed $some-old-sha1

По мере того, как будете тестировать, скажите git bisect-fixedили, git bisect-unfixedкак нужно .


5
Кстати, git не позволяет создавать псевдонимы подкоманд. Отсюда тире. Если это действительно возможно (или станет возможным), надеюсь, кто-нибудь обновит ответ.
Michael Wolf

3
Даже если вы используете псевдонимы, вывод из git не будет, поэтому он все равно будет сообщать foo is the first bad commit, поэтому кажется, что временное обучение все еще необходимо, не так ли?
ThomasW

2
Честная оценка. (Проголосовали за ваш комментарий.) Хотя даже в этом случае, надеюсь, это, по крайней мере, немного меньше дополнительной когнитивной нагрузки, с которой нужно иметь дело, и, как программисты, у нас уже есть много.
Майкл Вольф

1
Я рекомендую использовать псевдонимы «до» и «после». Таким образом, у вас не будет когнитивных накладных расходов на выполнение инверсии «когда я вижу ошибку, я должен написать« хорошо »»; вместо этого у вас есть только - вероятно меньшие - накладные расходы, связанные с запоминанием того, что вы ищете появления / исчезновения ошибки (т. е. помните, какого рода изменение вы ищете - «до чего?»).
Йонас Кёлькер

1
@ JonasKölker, это отличная идея. Я использовал предложенные псевдонимы в ответе, а также bisect-after = bisect badи bisect-before = bisect goodпо вашей рекомендации. Теперь я могу использовать любой набор псевдонимов. Посмотрим, какие из них я предпочитаю больше после нескольких применений.
Габриэль Стейплс

47

Я бы просто "обманул" мерзавца и поменял местами хорошее <=> плохое.

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

В любом случае, хорошее и плохое - довольно субъективные понятия, не так ли? :)

git bisect start
git bisect good last
git bisect bad master

2
Что ж, если вы думаете об этом, нет никакого общего значения, что такое хорошее или плохое (вероятно, даже в религии) ... это просто зависит от ваших целей. Таким образом, это не совсем обман - но, возможно, Git's Sin (оставаясь на религиозной теме: D означает использовать такой спорный термин, а не более нейтральный "цель" / "происхождение" .. Но да, философия может быть разумом. ошеломляюще ;-)
inger

Наверное, впервые я слышу, что ошибки могут быть «хорошими».
MarcH

1
Это то, что я сделал до того, как нашел этот вопрос. Я больше не собираюсь этого делать. Помните, достаточно всего одного неправильного ответа, прежде чем все деление пополам пойдет не так. Не теряйте рассудок.
proski

21

Если вы используете, git bisect runкак я, proveкоманду Perl (которая запускает автоматические тесты), у вас нет возможности просто поменять местами goodи bad. Об успешном выполнении тестов будет сообщено как код выхода.

Я нашел допустимый синтаксис Bash, который отменяет код выхода программы, выполняемой git bisect run:

git bisect start
git bisect bad HEAD                 # last revision known to PASS the tests
git bisect good $LAST_FAIL_REVISION # last revision known to FAIL the tests
git bisect run bash -c "! prove"

Это дало мне первую ревизию, которая прошла все тесты prove.


1
Я согласен, я бы предпочел не изменять свой тестовый пример, так что это идеально.
Seanlinsley

8

Git теперь позволяет использовать oldи newбез предварительного определения их. Вы должны вызвать git bisect startбез коммитов в качестве дополнительных аргументов, а затем правильно начать деление пополам, вызвав

git bisect old <rev>
git bisect new <rev>

https://git-scm.com/docs/git-bisect#_alternate_terms

По сути, это то, что предлагал @MarcH.


1
Это наиболее актуальный ответ (для современного git). И команда старта должна быть (по ссылке, которую вы поделили):git bisect start --term-new fixed --term-old broken
Сэм Проценко

Правда. Когда были представлены эти варианты? Я хочу обновить свой ответ.
Michael Wolf

@MichaelWolf Они появились в версии 2.7.0 .
GKFX

6

Псевдонимы Git - хорошая идея, однако термины fixedи unfixedимеют ту же проблему, что goodи и bad: вы не можете сделать так, чтобы они были совместимы как с регрессиями, так и с прогрессиями. Легко найти слова, которые работают в любом случае: просто возьмите их из исходной терминологии двоичного поиска, которая является нейтральной по своей природе, без предвзятого мнения о том, что хорошо, а что плохо. Например:

git config --global alias.bisect-high 'bisect bad'
git config --global alias.bisect-low  'bisect good'

Используя такие нейтральные термины, вы всегда можете ввести: git bisect-high(или git bisect-upper, или git-bisect max... на ваш выбор!) Независимо от того, ищете ли вы регресс или исправление .

Жаль, что разработчики git bisect не могли просто повторно использовать какие-либо существующие термины. Пользовательский интерфейс, вообще говоря, не является проблемой Git: http://stevebennett.me/2012/02/24/10-things-i-hate-about-git/


От: git.github.io/rev_news/2015/07/08/edition-5 «Некоторые серии патчей дорабатываются, чтобы позволить git bisect использовать произвольную пару терминов вместо хороших и плохих, ...»
MarcH
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.