GrabDuck

Пара приемов работы с git

:

При чтении обучающих статей про систему контроля версий git я заметил одно свойство, большинство из них направлено на то, чтобы читатель уяснил все плюсы распределенной системы контроля версий. В этом разрезе обычно рассказывают об удаленных репозиториях, ветках, пушах, пулах и т. д.

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

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

Но статья, на самом деле, не об этом. Я хочу рассказать про две замечательные команды git, которые я недавно для себя открыл. Это git blame и git bisect

Аннотация файла

Не редко случается ситуация, когда находишь в коде какой-то баг у жутко становится интересно, кто же это все написал и когда. (Еще конечно хочется знать, что он при этом думал и каким местом давил на кнопки, но тут конечно гит бессилен)

git blame позволяет посмотреть когда и кем редактировалась каждая строка файла в последний раз.

Следующая команда

git blame -L 12,22 products.php

покажет

ebf9cf99 (vasia 2011-11-16 15:07:52 +0400 260)$templates = $controller->getTemplates();
ebf9cf99 (vasia 2011-11-16 15:07:52 +0400 261)     foreach($templates as $value)

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

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

git blame -L 10,19 -C Controller.php

3351a8dc /logistics/pages/Controller.php (vasia 2012-01-24 15:26:04 +0400 10)
0cb0d219 /orders/pages/Controller.php    vasia 2012-01-13 09:51:54 +0400 16)

Удивительно потом обнаруживать, что автор этих изменений ни кто иной, как ты сам )

Бинарный поиск

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

Во-первых, запускаем механизм поиска и устанавливаем значение, что текущее состояние проекта нерабочее

git bisect start 
git bisect bad

Далее откатываемся на рабочее состояние проекта — на 10 коммитов назад по истории

git bisect good HEAD~10

Смотрим, проявляется ли этот баг в текущем состоянии. Допустим, сейчас с проектом все хорошо, поэтому продолжаем поиск дальше

git bisect good

Эта команда перематывает состояние проекта в середину, между хорошим коммитом и плохим, т. е. Сейчас мы находимся в пяти коммитах назад по истории. Если баг проявляется, то он находится до текущего коммита, если нет — то после. С каждой такой итерацией расстояние уменьшается в два раза, пока мы не находим плохой коммит (а главное — его автора, к сожалению, это его опять сделали мы).

После завершения поиска сбрасываем репозиторий в исходное состояние

git bisect reset

Вернувшись к вступлению, хочу сказать, что в обучении гиту для меня такой книгой, которая расставила бы все точки над ё, стала вот эта. Может быть не самое подробное изложение, но, на мой взляд, для перехода от состояния «я могу это сделать» до состояния «я могу это сделать и понимаю, почему нужно делать именно так» очень хороший вариант. Есть и ее перевод (правда не совсем полный) на русский язык.

На этом рассказ свой хочу закончить, надеюсь описанный функционал будет полезен в работе не только тем, кто только открывает для себя git.

UPD.
Для меркуриал данный функционал тоже существует, спасибо retran
blame — hg annotate
А для поиска есть специальный плагин — mercurial.selenic.com/wiki/BisectExtension

Для svn есть
svn blame TARGET[@REV]