30 ноября 2010 в 15:14

Hg Init: Часть 4. Исправляем ошибки перевод

Это четвертая часть из серии Hg Init: Учебное пособие по Mercurial от Джоэля Спольски (Joel Spolsky). Предыдущие части:


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

Часть 4. Исправляем ошибки




Mercurial позволяет свободно экспериментировать. Представьте, что во время работы вы что-то не то сделали в редакторе, и случилось нечто ужасное:





Emacs, как же я тебя люблю. Как бы то ни было, все можно исправить. Наиболее распространённым способом справиться с такими проблемами является использование команды hg revert:



hg revert
возвращает файлы к состоянию, зафиксированному в репозитории.


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



А что если все зашло слишком далеко и вы уже закоммитили?



Есть команда hg rollback, которая спасет вашу шкуру, но только если вы еще не протолкнули (push) ошибочный коммит в другой репозиторий. Эта команда отменяет один коммит.



hg rollback
отменяет один коммит, при условии, что вы не протолкнули его в другой репозиторий.


Представьте, что вы хотите поставить большой эксперимент в свободное время. Ваш босс нанял нового дизайнера, Джима. С тех пор дизайны, которые вы получаете, стали просто абсурдны. В них кислотный зеленый текст, ничего не выровнено (на это есть «художественные» причины, ага) и юзабилити хромает. Вы хотите прийти на работу в выходной и все переделать, но боитесь коммитить свои изменения, так как не уверены на 100%, что ваши идеи лучше, чем у этого рехнувшегося дизайнера. Джим курит траву практически все время с момента пробуждения до момента отхода ко сну. Вы не хотите использовать это против него, да и все думают, что эта привычка никого не касается до тех пор, пока дизайны в порядке. Но всему есть предел. Так ведь? И дизайны у Джима не в порядке, и вообще он дерзкий какой-то.

При работе с Mercurial вы можете просто создать клон всего репозитория:



Это не настолько расточительно, как может показаться. Так как в репозиториях recipes и recipes-experiment хранится одно и то же (пока), то Mercurial воспользуется "жёсткими ссылками" (hard links). А значит, копия репозитория будет создана быстро и не займет много дополнительного места на диске.

Теперь можно сделать ряд изменений в экспериментальной ветке:



Начинаем мой великий эксперимент над рецептом гуакамоле:



В экспериментальный репозиторий можно коммитить без опасений:



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

Если вы решите, что эксперимент не удался, то можете просто удалить весь каталог с экспериментальным репозиторием. Нет репозитория — нет проблемы.

Но если все получилось, то вам нужно лишь протолкнуть ваши новые правки:



И куда же они протолкнулись?



hg paths
отображает список известных удаленных (remote) репозиториев.


Строчка, начинающаяся с «default», содержит путь к репозиторию, в который hg push проталкивает изменения если вы явно не укажете другой репозиторий. Обычно в этой строчке указан путь к репозиторию, с которого вы делали клон. В данном случае это локальный каталог, но в качестве пути может быть и URL.



Не забывайте, что проталкивание изменений в этот репозиторий...



… не приводит к тому, что изменения появляются в рабочем каталоге.



hg parent
отображает набор изменений, находящийся в рабочем каталоге.


Видите? Правки про «Queso» в пятом наборе изменений. Но в моем основном репозитории работа остановилась на четвертом наборе изменений. От того, что кто-то протолкнул изменения в репозиторий, рабочий каталог не обновился, и пятый набор изменений в нем не появился. Так что я по-прежнему работаю с четвертым набором изменений.



Если я захочу узнать, что в пятом наборе изменений, то мне нужно будет использовать команду hg update:



Видите, что произошло? Изменения были получены, но они были после той версии, с которой я работал. Команды push и pull просто пересылают изменения между репозиториями. Эти команды не влияют на то, с чем я работаю в данный момент.

Сейчас репозитории выглядят так:



Mercurial гибок в вопросах пересылки изменений из репозитория в репозиторий. Можно протолкнуть изменения прямо из экспериментального в центральный репозиторий:



Так пятый набор изменений был отправлен из экспериментального прямиком в центральный репозиторий. Теперь, если я вернусь в свой основной репозиторий, то увижу, что в нем больше нечего проталкивать!



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

Дизайнер Джим, после того как ему предложили работу, пообещал приступить к делам сразу же. Однако он не появлялся на работе еще два месяца. Почти все уже забыли и о нем, и о том, что предлагали ему работу, так что когда он весь такой загорелый впервые появился в офисе, честно сказать, никто толком не мог понять, кто он и что вообще происходит. Это было достаточно забавно. Внешность у него типическая. В конце концов, во всем разобрались, но так как он был новеньким, все постеснялись спросить у него, что, черт побери, произошло. И про шрамы и синяки на лице тоже не спросили. Неважно. Просто мы ненавидим этого парня.

Иногда случается, что спустя месяцы, вы обнаруживаете, что сделали ошибку.



Картофельные чипсы? Чё за..?!

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



Матерь божья, что это было?



Вообще говоря, времени могло пройти много. Чипсы вообще могли исчезнуть из рецепта. Много всего жуткого могло произойти. А значит, иногда после изъятия ревизии объединить изменения невозможно. В таких случаях вы получите конфликты слияния (merge conflicts), которые вам нужно как-то разрешить. Вот об этом и поговорим в следующей части.

Проверь себя


Вот то, что вы должны уметь делать после прочтения данной части:
  1. Откатить случайные изменения. До того, как они зафиксированы в репозитории, и после.
  2. Локально склонировать репозиторий для экспериментов.
  3. Проталкивать изменения в разные репозитории.
  4. Откатить старую ошибку, которая давным-давно была зафиксирована в репозитории.


Продолжение здесь:
Hg Init: Часть 5. Процесс слияния
Перевод: Joel Spolsky
Сергей Бобровский @Bobrovsky
карма
145,0
рейтинг 0,0
Похожие публикации
Самое читаемое Разработка

Комментарии (36)

  • +2
    читаю эти статьи и дико горжусь выбором mercurial в своих проектах. простая и удобная DVCS.
  • 0
    ooshsmay allway ingredientsway ogetherawy. Ervesay ithway otatopay ipschay.
    Что это за заклинание?
    • 0
      Поросячий латинский. «Волшебный кролик» в исполнении программистов. Ну и шуточки.
  • 0
    Mercurial воспользуется «жёсткими ссылками» (hard links)

    Это справедливо видимо только для *nix систем, т.к. в windows такого поведения не наблюдается
    • 0
      NTFS умеет хардлинки. И под виндами Mercurial их тоже использует. Точно.
      • 0
        сейчас склонировал с одного локального репозитория в соседний — никаких жестких ссылок (Win 7, NTFS)
        • 0
          скорее всего, вы заблуждаетесь. почитайте ru.wikipedia.org/wiki/Hardlink для начала.
          • 0
            ок. проверил еще раз более тщательно на свежем репзитории — действительно работает, спасибо:)

            Но, все-равно в статье нужно уточнить, что жесткие ссылки создаются только для структуры самого репозитория, а не файлов в нем.
            • 0
              Ну правильно, ведь «рабочая копия» заведомо меньше размером, чем вся история
    • 0
      на дисках с ntfs есть жеские ссылки.
    • 0
      Хотя в примерах именно Windows :)
      C:\Users\Joel>
      • 0
        Ну это же Joel — он известный любитель Windows и крайне эпатажных статей, призывающих под какие-нибудь очередные знамена. На этот раз, видимо, под знамена Mercurial, впрочем, как обычно, не объясняя ни разу, зачем и почему…
        • 0
          На этот раз, видимо, под знамена Mercurial, впрочем, как обычно, не объясняя ни разу, зачем и почему…
          «Часть 4» в заголовке топика и ссылки на предыдущие части, вы, надо понимать, предпочли не заметить?
          • +2
            Я, в общем, и оригинал в своё время читал, и здесь за переводами внимательно слежу. Возможно, мне одному обилие фраз в повелительном наклонении («Запомните!», «поверьте!») и прочих, мягко говоря, спорных утверждений, выдаваемых за непреклонную истину (обычно обернутых во фразы типа «общепринято») кажется несколько странным стилем изложения для обучающих материалов, коими по идее должны быть эти статьи…
            • +1
              А. Ну я не вчитывался в собственно статьи, каюсь — в своё время освоил hg самостоятельно.

              В принципе, странный стиль, согласен. С другой стороны, текст для полных новичков и различные оговорки и километровые сноски могут навредить. Discuss?
              • +3
                Текст на самом деле является художественной переработкой Mercurial: The Definitive Guide — порядок изложения и некоторые характерные ходы выдают. Переработка же произведена в характерном (по крайней мере, как мне кажется) для Joel стиле — выкинуть все объяснения (сложно, напугает новичков, зачем им), понабросать побольше красивых лозунгов («Mercurial — круто! Subversion — отстой! повторяйте за мной!») и разбавить историями про воображаемых коллег, косячки, красивую хипстерскую реальность кремниевой долины.

                Некоторым нравится.
  • +1
    Единственное, что пока мне кажется неудобным — игнорирование папок (хотелось бы фиксировать структуру с пустыми папками). Несмотря на это попробую hg в будущих проектах.
    • 0
      Фиксировать структуру папок можно помещая в них пустые файлы.
      • 0
        Или создать build-скрипт, который позаботится о том, чтобы все необходимые папки были созданы. Мне этот вариант кажется более удобным, т.к. не нужно захламлять проект и более простым, т.к. список папок будет храниться в build-скрипте, что позволит его с легкостью изменять в будущем.
        • 0
          спасибо, я читал про эти варианты. только не греют они душу)
      • 0
        Есть ещё практика помещения в такие папки файликов вида .ignore с маской *
  • 0
    Может немного забегаю вперёд, но есть вопрос: какая практика ветвления/объединения при разработке используется чаще/удобнее: один локальный клон у одного центрального репозитория с ветками у одного пользователя или множество клонов центрального репозитория у одного пользователя?

    Может на примере будет понятней, что хочется понять:
    Есть production, staging и development сервера, есть несколько разработчиков, каждый из которых одновременно (в глобальных масштабах :) ) работает над несколькими фичами/багфиксами проекта. Можно организовать так, что у каждого сервера будет свой клон центрального репозитория и у разработчиков клон для каждой фичи/багфикса, можно использовать для каждого сервера/фичи ветки (branch), можно как-то комбинировать (ветки для серверов, клоны для фич).

    Как лучше (проще поддерживать актуальность, удобней пользоваться и т. п.) и почему?

    И ещё маленький вопросик — какие традиционные имена у основных репозиториев/веток (аналог TRUNK в Subversion)?
    • +1
      какая практика ветвления/объединения при разработке используется чаще/удобнее
      ну вот есть mercurial.selenic.com/wiki/WorkingPractices — выбирайте/спрашивайте более предметно.
      какие традиционные имена у основных репозиториев/веток
      никаких. есть только tip — закладка на последний коммит.
    • +1
      Я думаю, шестая (последняя часть) именно об этом.
      Если кратко, то есть разные практики, Джоэль (автор этого пособия) советует для веток заводить отдельные клоны репозитория.
      • 0
        Как мне кажется, клоны удобны для небольших временных ответвлений, типа разработки фичи или фикса бага, то есть собственно для локального процесса разработки. А вот ветки хороши для организационного статического деления со строгим контролем прав, автоматическим тестированием, сборкой, публикацией по коммитам. Но это пока только взгляд со стороны, надо смотреть на практике.
    • +1
      Есть отличная статья от Steve Losh, в которой рассмотрены разные практики с их плюсами и минусами: stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/

      Если на русском, перевод тут: pqr7.wordpress.com/2010/10/10/a-guide-to-branching-in-mercurial/
      • 0
        Спасибо, добавили информации к размышлению :)
  • 0
    Жаль, что в цикле статей нет ничего о rebase
    • +2
      rebase — это следствие локальных по умолчанию веток в git. лично меня вполне устраивает шаринг по умолчанию всего кода — мне нечего скрывать от коллег ;)
      рискну предложить почитать «Programmer Insecurity» (по ссылке перевод на русский).
      • 0
        причем тут git? и кого скрывать? я не понимаю о чем вы.

        Вот тут отличная статья про сравнение rebase и merge Mercurial workflows: mainline workflow

        Мне просто не нравиться постоянные мерджи и миллирды веток в истории правок. Вот так выглядит наш репозиторий:

        • 0
          А. Нууу… для таких случаев в коробке лежит mercurial.selenic.com/wiki/RebaseExtension
          • 0
            Да я знаю что они есть, обидно что Джоель не написал про rebase, transplant, purge и прочих клёвых расширениях для меркуриала.
  • 0
    Так как в Hg хранить модули проекта, которые хочется менеджить отдельно друг от друга? Это должны быть отдельные репозитории? Насколько это удобно? Можно ли сделать update для всех модулей из всех репозиториев одним движением руки?
  • 0
    почитайте про деревья в Hg

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

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.