17.06.2010Ещё два сценария работы с git: git stash и git bisect
Введение
Моя любимая система контроля версий имеет огромное количество инструментов. Как-то раз я участвовал в опросе, после которого выяснилось, что даже из самых популярных инструментов я использую от силы 10%.
Но иногда возникают ситуации, единственно продуктивным выходом из которых бывает изучение и использование нового для себя инструмента. О двух таких случаях я сегодня и расскажу.
Внезапные просьбы: git stash
Бывает так, что пока я работаю над нововведениями в программу, текущая стабильная её версия активно используется. При активном использовании, конечно же, могут возникнуть ошибки или пожелания что-то изменить. Бывает так, что при этом я нахожусь в середине тестирования какого-то новшества, и всё настолько сыро, что я даже не могу сделать коммит.
Итак, я нахожусь в середине правок на ветке extremely_experimental, а мне необходимо внести правки в ветку master. Вот, как это делается:
git stash save
git checkout master
После первой команды всё наши изменения, которые нельзя было закоммитить, сохранены и текущая ветка приведена в состояние до правок. После этого мы можем сменить ветку и внести наши правки. После того, как ошибки исправлены, нововведения сделаны и тесты проходят, мы можем вернуться обратно к нашим правкам.
Но скорее всего все или некоторые из сделанных изменений понадобятся нам в нашей экспериментальной ветке. После перехода на неё:
git checkout extremely_experimental
Если нам нужны все изменения, то:
git merge master
Если только некоторые, то:
git cherry-pick ...
После этого вернём наши правки:
git stash pop
Если возникли конфликты, то правим их и делаем:
git stash drop
git reset --mixed
Последнее нужно для того, чтобы вынести наши правки из индекса, т.к. при конфликте они не выходят оттуда самостоятельно.
Конечно же таких незавершённых правок может быть несколько, но это я оставлю на самостоятельное изучение пытливому читателю.
Неизвестно, когда сломалось: git bisect
Бывает так, что вдруг обнаруживается ошибка, про которую точно известно, что давным давно её не было. Так бывает в больших проектах, в непокрытых тестами областях. Бывает так, что обнаружить, в чём же дело, быстро не удаётся.
Хорошая новость в том, что это и не обязательно. Нужно просто начать процесс:
git bisect start
git bisect bad
Так мы обозначили, что текущий коммит содержит ошибку. После этого, либо мы знаем, как называется коммит, в котором ошибки ещё не было, или находим его.
git bisect good v2.3.1
или
git checkout ...
git bisect good
После этого за нас всё будет делать git. Он будет перемещать нас по истории, а мы будем проверять, есть эта ошибка или нет, и сообщать об этом:
git bisect good
или
git bisect bad
В конце концов нам сообщат, какой именно коммит всё поломал. Название инструмента подсказывает нам, что на тестирование нам всегда предоставляется коммит, который находится посередине между плохим и хорошим. Таким образом, мы просматриваем не все N коммитов в истории ошибки, а всего лишь log2N.
После того, как мы выяснили, в чём причина, убрать следы, которые оставил после себя git bisect можно так:
git bisect reset
А какими инструментами git пользуетесь вы?