четверг, 3 марта 2016 г.

Налажал с коммитом в Mercurial, команды для фикса

Сухая теория


Я предполагаю, что вы уже знакомы с Mercurial, и не описываю типовые команды:

hg st
hg sum
hg pull -u
hg ci -m "Bugfix"
hg push

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

hg amend


Команда позволяет добавить новые файлики к твоему коммиту и менять текст сообщения.

Допустим, закоммитила я пять автотестов, еще не пушила:

hg ci -m "add 5 tests"

Написала еще два. Можно сделать второй коммит, а можно добавить к текущему:

hg amend

Можно изменить текст сообщения:

hg amend -m "add 7 tests"

Если новых файликов нет, команда просто меняет текст последнего коммита. Это помогает, если у вас стоят хинты на команду push, которые проверяют соответствие комментария паттерну и не дают запушить всякую хреноту. Облажался? Не проблема, измени текст амендом.

См также:
User guide — поподробнее о команде


hg rebase


Если вы продолбали сделать pull перед своим коммитом, а кто-то успел закоммититься до вас — создается «параллельная реальность».

На пальцах — идет одна ветка разработки, обычно именуемая trunk. Там уже есть изменения 1 и 2. Вася с Олей работают у себя с версией 2.

Вася напилил свой код и сделал коммит 3.
Оля напилила автотестов и сделала коммит 4, забыв сделать pull и всосать Ванин коммит 3. А потом напилила еще пару тестов и сделала коммит 5.

Если забыл сделать pull — коммит создает новую «голову»

Что делать?

Я обычно делаю merge :) Накоммитил свое, видишь, что появилась новая голова в ветке, чертыхаешься, потом:

hg pull -u
hg merge
hg ci - m "fucking merge"
hg push

Граф в этом случае получается не шибко красивый, но «работает — не трогай!» Smile :)

Вместо мерджа можно использовать команду

hg rebase

И она объединит твои коммиты с остальными. То есть как будто бы 4 коммит шел не после 2, а после 3.
hg rebase — делает так, как будто ты не забывал про pull

И все хорошо и весело!
Хотя лучше исходно не забывать про pull...


hg strip


Это полный откат на какую-то прошлую ревизию, если сделал и покоммитил ну вообще не то.


Смачная практика


С чего вдруг я вообще пишу этот блог-пост и познаю новые команды? Вспоминается bash.im:

KKK: клево. наши админы 5 лет делали бекапы sql, которые невозможно развернуть
KKK: легко догадаться как это выяснилось
© #429757

Ну вы поняли Smile :)

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

Пример коммита:

hg ci - m "INT-22 my little pony"



Разработка у нас ведется в основной ветке — trunk.
Когда выпускается релиз, создаем branch от trunk-а.
Когда делаем БОЛЬШУЮ и жирную фичу — делаем ее в отдельном бранче, чтобы не мешалась в транке и не застопорила выпуск релиза. Бранчу обычно даем имя "feature-<номер задачи в JIRA>"

Итак, делаем большую фичу, допустим, по задаче INT-22. Так как она идет «сквозь» релизы, делается в отдельном фича-бранче feature-int-22. Туда же я и пишу автотесты.

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

Итого у меня:
— 10 файлов в меркуриале изменены (исправляла старые тесты)
— 2 новых файла добавлено, они пока unversioned.

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

Коммит файлов я делаю из IDEA — где пишу, оттуда и commit + push. А вот прыжки по веткам и мердж — из командной строки. Привычка Smile :)

Раньше я всегда пушила все коммиты. Допустим, вносим изменения в бранч прошлого релиза: коммит в бранч, пуш, обновиться на транк, коммит и пуш:

hg ci -m "branch changes"
hg push
hg up default
hg merge branch-1
hg ci -m "merge"
hg push

Потом это увидел наш архитектор и стал возмущаться, как неправильно я делаю, надо push делать один, итоговый:

hg ci -m "branch changes"
hg up default
hg merge branch-1
hg ci -m "merge"
hg push

Ну, мне не сложно, стала делать так.

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

hg ci - m "feature-int-22 my little pony"

Вместо номера задачи я пишу название ветки. Но коммит настолько отведен до автомата, что я вижу ошибку краем глаза, а рука уже нажимает «commit».

При этом глобальной ошибки до меня еще не дошла. Мне бы сделать реверт, или amend. Или на худой конец push, как я делала раньше — он бы сразу упал и сказал «ты налажала в тексте». И исправление бы было простым.

Но нет, я перехожу в командную строку:

hg up default
hg merge feature-int-22
hg ci -m "int-22 merge"

Добавляю новые файлы сразу в транк, делаю еще один коммит и вот он, пуш:

hg ci -m "int-22 new tests"
hg push

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

Мелькнула мысль, что самым простым решением проблемы будет на 2 минуты снять хинт меркуриала, чтобы можно было запушить любой текст. Это была очень умная мысль! Стояло прислушаться )))

Но нет, я присуммонила разработчика, который проделал magic и «все стало хорошо». Потом он рассказал мне про эти три команды. А я их законспектировала. На будущее Smile :)

Правда, там получилось не совсем все хорошо, но это уже другая история ))))

Комментариев нет:

Отправить комментарий