Показать страницуИстория страницыСсылки сюдаCopy this pageExport to MarkdownODT преобразованиеНаверх Вы загрузили старую версию документа! Сохранив её, вы создадите новую текущую версию с этим содержимым. Медиафайлы{{tag>scm mercurial hg}} ====== Основы Mercurial. Часть 2. ====== <html> <div class="content"> <img src="http://habrastorage.org/storage/eebea7f1/5482efc4/01467053/55589e0f.png" align="left">Это вторая часть из серии <b>Hg Init: Учебное пособие по Mercurial</b> от Джоэля Спольски (<a href="http://www.joelonsoftware.com/">Joel Spolsky</a>). Возможно, вы захотите прочитать и первую часть [[hg_init:часть_1._переобучение_для_пользователей_subversion|]].<br> <br> Даже если вы работаете в одиночку, то вам стоит использовать Mercurial. Так вы сможете получить все прелести контроля версий. Эта часть покажет насколько просто добавить каталог в Mercurial, чтобы с легкостью отслеживать предыдущие версии.<br> <br> <h4>Часть 2. Основы Mercurial</h4><br> <br> <img src="http://habrastorage.org/storage/a2dc0ced/1ebe349c/adafba84/cf7127dd.png" align="left">Mercurial — это <i>система контроля версий</i>. Разработчики используют ее для администрирования исходного кода. У нее два основных назначения:<br> <ol> <li>Она хранит все предыдущие версии каждого файла</li> <li>Она может объединить разные версии вашего кода, то есть сотрудники могут независимо работать над кодом и затем объединять свои изменения</li> </ol><br> <br> <a name="habracut"></a><br> <br> Без Mercurial вы могли бы попытаться сохранить предыдущие версии, просто создавая много копий каталога с кодом:<br> <br> <img src="http://habrastorage.org/storage/c204c8c2/8cbde270/f057de30/d4010d6d.png"><br> <br> Это муторно, требует много места на диске и создает путаницу. Лучше использовать систему контроля версий.<br> <br> Большинство людей работают с Mercurial через интерфейс командной строки. Так можно работать в Windows, Unix, и Mac. Команда для Mercurial — это <code>hg</code>:<br> <br> <img src="http://habrastorage.org/storage/d1a7ded2/0e111d9f/ff11aa6a/06d714d8.png"><br> <br> Если выполнить <code>hg</code> без параметров, то вы получите список наиболее часто используемых команд. Вы можете также попробовать выполнить <code>hg help</code> для получения полного списка команд.<br> <br> Для того чтобы воспользоваться преимуществами контроля версий, вам нужен <i>репозиторий</i>. Репозиторий хранит все предыдущие версии всех ваших файлов. На самом деле, для экономии места на диске, все предыдущие версии не будут храниться — будет храниться только компактный список изменений.<br> <br> В старые времена заиметь репозиторий было большим делом. Вам было необходимо иметь центральный сервер и нужно было установить на него программное обеспечение. Mercurial — <i>распределенная</i> система, так что вы можете использовать ее без модного центрального сервера. Вы можете пользоваться Mercurial, используя один только свой компьютер. А заполучить репозиторий супер просто: вы просто идете в каталог с вашим кодом…<br> <br> <img src="http://habrastorage.org/storage/df024955/0a7c68ad/4d8a48b9/032e8174.png"><br> <br> … и выполняете команду <code>hg init</code>:<br> <br> <img src="http://habrastorage.org/storage/6d17bad7/1023e58b/cbf778f1/de0f8775.png"><br> <br> <blockquote><code>hg init</code><br> создает репозиторий.<br> </blockquote><br> <br> Минуточку, а разве что-то произошло? Выглядит так, словно ничего не поменялось. Нет, если вы присмотритесь получше, то увидите, что появился новый каталог <code>.hg</code>:<br> <br> <img src="http://habrastorage.org/storage/8f6b4eec/b4aa6daf/c822a60f/ea555032.png"><br> <br> Это и есть репозиторий! Это каталог со всем, что нужно Mercurial для работы. Настройки, предыдущие версии файлов, теги, лишняя пара носков на случай дождя, и прочее. <i>Не лазьте туда.</i> Вам почти всегда не стоит возиться с этим каталогом самостоятельно.<br> <br> Ну хорошо, раз у нас теперь есть свежеиспеченный репозиторий, то мы захотим добавить в него все исходные файлы. Это тоже просто: нужно лишь выполнить <code>hg add</code>.<br> <br> <img src="http://habrastorage.org/storage/0deb8fc5/d3543931/6114cd9a/f166b892.png"><br> <br> <blockquote><code>hg add</code><br> помечает файлы как запланированные для добавления в репозиторий. Файлы на самом деле не будут добавлены до тех пор, пока вы не зафиксируете изменения.<br> </blockquote><br> <br> Остался еще один шаг… вам нужно <i>зафиксировать ваши изменения</i>. Какие изменения? Факт добавления всех этих файлов.<br> <br> Почему вы вынуждены фиксировать изменения? При работе с Mercurial фиксирование изменений означает: «Эй, вот как файлы сейчас выглядят, так их и запомни, пожалуйста». Это как создание копии всего каталога… каждый раз, когда у вас есть что-то измененное, и оно вам типа нравится, то вы фиксируете изменения.<br> <br> <blockquote><code>hg commit</code><br> сохраняет текущее состояние всех файлов в репозиторий.<br> </blockquote><br> <br> <img src="http://habrastorage.org/storage/1b0b9bd3/265a2c06/84473f38/64028691.png"><br> <br> Mercurial запустит редактор для того, чтобы вы могли напечатать комментарий к изменениям. Вам нужно просто написать что-нибудь, что напомнит вам о сделанных изменениях.<br> <br> <img src="http://habrastorage.org/storage/d47213d9/eab868b9/894d01ae/68290364.png"><br> <br> После сохранения и выхода из редактора ваши изменения будут зафиксированы.<br> <br> Вы можете выполнить <code>hg log</code> для просмотра истории изменений. Это как блог для вашего репозитория:<br> <br> <img src="http://habrastorage.org/storage/63c37c68/7c4b9074/79365c85/9158e135.png"><br> <br> <blockquote><code>hg log</code><br> отображает историю изменений, зафиксированных в репозитории.<br> </blockquote><br> <br> Давайте изменим файл и посмотрим, что получится.<br> <br> <img src="http://habrastorage.org/storage/a4976b63/e1120125/f2d75af8/175793cf.png"><br> <br> Так как мы сделали изменение, то можем его зафиксировать при помощи <code>hg commit</code>:<br> <br> <img src="http://habrastorage.org/storage/1b0b9bd3/265a2c06/84473f38/64028691.png"><br> <br> Обратите внимание, что Mercurial догадался, что только один файл, a.txt, изменен:<br> <br> <img src="http://habrastorage.org/storage/7e7e4f7c/44a2a982/429514a6/ea1f8d40.png"><br> <br> А теперь, после того как я закоммитил (зафиксировал изменения), давайте посмотрим на историю:<br> <br> <img src="http://habrastorage.org/storage/30655b31/b8a4769b/cabb993c/cd4bad09.png"><br> <br> Как любой нынешний блоггер, Mercurial помещает самое новое в начало.<br> <br> Я собираюсь сделать еще одно изменение, просто чтобы потешить себя.<br> <br> <img src="http://habrastorage.org/storage/ce916884/653f2957/8d61c6eb/daeab3db.png"><br> <br> Коммичу (фиксирую изменения):<br> <br> <img src="http://habrastorage.org/storage/1b0b9bd3/265a2c06/84473f38/64028691.png"><br> <br> Мое сообщение к коммиту:<br> <br> <img src="http://habrastorage.org/storage/64909d63/4d121c11/5243ddb9/f16bd56c.png"><br> <br> А что у нас теперь в истории?<br> <br> <img src="http://habrastorage.org/storage/f8759acb/815f0236/1614fff7/7b5449b8.png"><br> <br> Хорошо, это было весело. Я сделал несколько изменений и каждый раз, сделав значимое изменение, я фиксировал его в репозитории.<br> <br> Я знаю, вы сейчас думаете: «ДЖОЭЛЬ, ВСЕ ЭТО ВЫГЛЯДИТ ПУСТОЙ ТРАТОЙ ВРЕМЕНИ». К чему вся эта катавасия с коммитами?<br> <br> Терпение, мой юный друг. Ты вот-вот узнаешь, как извлечь выгоду из всего этого.<br> <br> Для начала: скажем, вы сделали большую ошибку в процессе редактирования.<br> <br> <img src="http://habrastorage.org/storage/1e32f444/b934daf5/5dab5b35/d90f3dec.png"><br> <br> А затем, боже ж мой, в дополнение ко всему вы удалили пару очень важных файлов.<br> <br> <img src="http://habrastorage.org/storage/74f57309/93aecdca/9cb11413/afb87796.png"><br> <br> Во времена, когда не было Mercurial, это все могло бы стать неплохим поводом для похода к системному администратору. Там, со слезами на глазах, вы бы задали ему пронзительно грустный вопрос: «Почему система резервного копирования „временно“ не работает все последние восемь месяцев».<br> <br> Системный администратор, которого все зовут <a href="http://ru.wikipedia.org/wiki/%D0%A2%D0%B0%D0%BA%D0%BE">Тако</a>, слишком скромен и не обедает с остальной командой. В тех редких случаях, когда он не сидит в своем кресле на колесиках, можно увидеть треугольное пятно цвета <a href="http://ru.wikipedia.org/wiki/%D0%A1%D0%B0%D0%BB%D1%8C%D1%81%D0%B0_(%D1%81%D0%BE%D1%83%D1%81)">сальсы</a> там, где падали, пролетев между ног, капли от его мексиканских закусок. Эти капли гарантируют, что никто не возьмет его кресло, хотя это <a href="http://hermanmiller.com/Products/Aeron-Chairs">одно из превосходных кресел от Herman Miller</a>, купленных учредителями компании для себя любимых, а не обычное бюджетное офисное нечто, из-за которого у всех болят спины.<br> <br> В любом случае, резервной копии нет, ага.<br> <br> Благодаря Mercurial, если вам не нравится то, что вы сделали, вы можете выполнить удобную команду <code>hg revert</code>, которая немедленно вернет ваш каталог к виду, в котором он был в момент последнего коммита.<br> <br> <img src="http://habrastorage.org/storage/faad2087/64fce902/eb83246d/28a37ffa.png"><br> <br> <blockquote><code>hg revert</code><br> возвращает измененные файлы к зафиксированному в репозитории виду.<br> </blockquote><br> <br> Я использовал аргумент <code>--all</code>, потому что хотел вернуть <i>все</i> файлы к прежнему состоянию.<br> <br> Таким образом, когда вы работаете над исходным кодом, используя Mercurial, вы:<br> <ol> <li>Делаете изменения</li> <li>Оцениваете, подходят ли они</li> <li>Если подходят, то выполняете <code>commit</code></li> <li>Если не подходят, то выполняете <code>revert</code></li> <li>GOTO 1</li> </ol><br> <br> (Я знаю. Пользуюсь командной строкой, в Windows, да еще и оператором GOTO — я <i>самый стрёмный программер</i> из всех, когда-либо живших.)<br> <br> Со временем вы можете забыть, на чем остановились и что поменяли с момента прошлого коммита. Mercurial отслеживает все это для вас. Все что вам нужно, это выполнить <code>hg status</code> и Mercurial даст вам список измененных файлов.<br> <br> <blockquote><code>hg status</code><br> отображает список измененных файлов.<br> </blockquote><br> <br> Предположим, я создал один файл, отредактировал другой и удалил третий.<br> <br> <img src="http://habrastorage.org/storage/3e908ca1/4cb8b4cf/daa03ab7/07f0f673.png"><br> <br> <code>hg status</code> отображает список измененных файлов, добавляя значок в начале каждой строки. Этот значок сообщает о том, что же произошло. «M» означаете «Modified» — файл был изменен. "!" означает отсутствие — файл должен быть здесь, но куда-то делся. "?" означает что, состояние не определено — Mercurial ничего не знает про этот файл. Пока не знает.<br> <br> Давайте разбираться с изменениями поочередно. Вот что поменялось в файле <b>a.txt</b>? Вы ведь можете забыть, что изменили. Чёрт, да я едва помню что я обычно ем на завтрак. А особенно внушает опасения то, что это всегда хрустящие колечки <a href="http://www.nestle.ru/products/breakfast/forchildren/cheerios/default.aspx">CHEERIOS</a>. В любом случае, a.txt изменен. Что поменялось?<br> <br> А есть команда для этого: <code>hg diff</code> сообщит вам в точности, что произошло с файлом с прошлого коммита.<br> <br> <blockquote><code>hg diff</code><br> показывает, что изменилось в файле.<br> </blockquote><br> <br> <img src="http://habrastorage.org/storage/cadb3342/3816d012/1d850a8a/8548d3b2.png"><br> <br> Формат результата немного непонятный, но самое важное, что вы можете видеть строки, начинающиеся с минуса (это то, что было удалено), и строки, начинающиеся с плюса (это то, что добавлено). Таким образом, вы можете видеть, что «Normal people» было заменено на «Civilians».<br> <br> Теперь про тот пропавший файл <b>favicon.ico</b>. Как уже было сказано, если вы на самом деле не планировали его удалять, то можете выполнить команду <code>hg revert</code> для восстановления. Но, предположим, что вы на самом деле хотели его удалить. При каждом удалении (или добавлении) файла вы обязаны сообщить об этом событии Mercurial.<br> <br> <blockquote><code>hg remove</code><br> помечает файлы как запланированные для удаления из репозитория. Файлы на диске не будут удалены до тех пор, пока вы не зафиксируете изменения.<br> </blockquote><br> <br> <img src="http://habrastorage.org/storage/1adbcbec/9083b063/0f042dfc/a90411e4.png"><br> <br> «R» означает «Removed», то есть, помечен для удаления. Во время следующего коммита Mercurial удалит этот файл. (<i>История</i> для этого файла сохранится в репозитории, так что, конечно, мы всегда сможем получить его назад.) И, наконец, нужно добавить этот новый файл <b>b.txt</b>:<br> <br> <img src="http://habrastorage.org/storage/c5e7f2af/f381ca0f/f30fd73b/48e0a4ff.png"><br> <br> «A» означает «Added», то есть, помечен для добавления. Заметили, что я разленился писать <code>hg status</code> каждый раз? Для Mercurial достаточно минимального набора букв, однозначно определяющего команду, а на <code>st</code> начинается только одна команда.<br> <br> Разобравшись с вопросиками и восклицательными знаками, я могу продолжить и внести изменения:<br> <br> <img src="http://habrastorage.org/storage/3304169d/c5c0285c/c62c0461/b51d2474.png"><br> <br> На что еще стоит обратить внимание в выводе <code>hg log</code>: строка <i>changeset</i> отображает номер каждого коммита. На самом деле даже два номера: короткий удобный вроде «0» для первой ревизии и длинный непонятный шестнадцатеричный, на который вы можете пока не обращать внимания.<br> <br> Запомните, что Mercurial хранит в репозитории достаточно информации для воссоздания любой версии любого файла.<br> <br> Прежде всего, при помощи простой команды <code>hg cat</code> вы можете вывести содержимое любой версии любого файла в консоль. К примеру, вот как увидеть, что сейчас находится в файле a.txt:<br> <br> <img src="http://habrastorage.org/storage/765630ca/414f3878/ec7f20ab/3bc776b0.png"><br> <br> <blockquote><code>hg cat</code><br> отображает содержимое любого файла для любой ревизии.<br> </blockquote><br> <br> Для того чтобы увидеть как файл выглядел раньше, я могу просто указать нужный номер набора изменений (changeset из лога) при помощи аргумента <code>-r</code> («revision», то есть ревизия):<br> <br> <img src="http://habrastorage.org/storage/c268d14f/b5655b3d/3b7bf975/f3251569.png"><br> <br> Если у файла сложное содержимое или большая длина, а изменился он лишь немного, то я могу использовать команду <code>hg diff</code> с аргументом <code>r</code> для вывода разницы между двумя ревизиями. К примеру, вот как посмотреть разницу между ревизиями 0 и 1:<br> <br> <img src="http://habrastorage.org/storage/206febdc/576f891d/25c37414/7901a60f.png"><br> <br> И наконец,- надеюсь, что вы еще не свалились от усталости,- прежде чем закончить эту часть, я хочу показать вам еще <i>одну маленькую фишку</i>: при помощи команды <code>hg update</code> вы можете перемещаться вперед и назад ко времени создания любой ревизии. Ну, <i>по сути</i> в будущее вы перемещаться не сможете, хотя это было бы супер круто, да. Вы, имея всего четыре ревизии, смогли бы выполнить <code>hg update -r 103994</code> и получить реально крутую версию ваших исходников. С гравицапой и прочими футуристическими штучками. Но, конечно, это невозможно.<br> <br> Что на самом деле возможно, так это вернуться к любой ревизии. Следите за руками:<br> <br> <img src="http://habrastorage.org/storage/0c666f35/3ec21ad5/a99e8dc1/86a101c4.png"><br> <br> <blockquote><code>hg update</code><br> приводит рабочий каталог к состоянию, как у заданной ревизии.<br> </blockquote><br> <br> Фактически, для перемещении вперед и назад между ревизиями <code>hg update</code> вносит в файлы запомненные изменения. Если файл был добавлен или удален, то эта команда добавляет или удаляет его на диске. Выполнение <code>hg update</code> без дополнительных параметров приводит рабочий каталог к состоянию как у самой свежей ревизии.<br> <br> <h5>Проверь себя</h5><br> <br> Отлично! Эта часть закончена. Вот все, что вы должны уметь делать на данный момент:<br> <ol> <li>Создать репозиторий</li> <li>Добавить или удалить файлы из репозитория</li> <li>После внесения изменений просмотреть, что было сделано, а затем</li> <li>… зафиксировать изменения, если они вам нравятся</li> <li>… или откатить изменения, если не нравятся</li> <li>Просмотреть предыдущие версии файлов или привести рабочий каталог к состоянию как у некоторой ревизии.</li> </ol><br> </html> **Продолжение здесь:** [[Hg Init: Часть 3. Привыкаем работать в команде|Hg Init: Часть 3. Привыкаем работать в команде]] СохранитьПросмотрРазличияОтменить Сводка изменений Примечание: редактируя эту страницу, вы соглашаетесь на использование своего вклада на условиях следующей лицензии: CC0 1.0 Universal