Почему команда hg update сливается в некоторых сценариях, но не во всех? - PullRequest
4 голосов
/ 13 августа 2011

Случай 1: Обновление рабочего каталога

$ hg update [-r REV]

Это переключает рабочий каталог на указанную ревизию. Однако, если мой рабочий каталог изменил изменения, изменения объединены обратно с REV. Я понимаю, что могу использовать флаг -C, чтобы отменить свои изменения, но я пытаюсь выразить свою обеспокоенность поведением команды update в различных сценариях.

Случай 2: переключение на филиал

$ hg update <bname>

Это переключает мой рабочий каталог на ветку <bname>. Однако мои незафиксированные изменения не объединены , пока я не использую команду merge явно.

Случай 3: Обновление вытащенных наборов изменений из удаленного репозитория

$ hg pull
$ hg update

Это снова объединяет моего рабочего каталога с наборами изменений из удаленного репозитория после недавнего pull.

Ответы [ 2 ]

5 голосов
/ 14 августа 2011

Mercurial 1.9.1

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

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

Когда Mercurial объединит незафиксированные изменения:

  • Обновление в той же ветке:

    --A1----A3----A5---wd
       \          /
        A2------A4
    

    Выше были внесены изменения на основе A5 . Если вы обновите файл до A4 , Mercurial объединит незафиксированные изменения для их передачи.

    --A1----A3----A5---A6---wd
       \          /
        A2------A4
    

    Кроме того, если есть дополнительные наборы изменений (например, A6 ), это все равно будет работать, потому что A4

  • Обновление в другую ветку (на этот раз обновление до B4):

    --A1----A3----A5---wd
       \          /
        B2------B4
    

    Выше, ревизии 2 и 4 находятся в другой ветви B , которая недавно была объединена с веткой A . Mercurial также передает незафиксированные изменения, потому что A5 и B4 так тесно связаны. А также:

    --A1----A3----A5---A6---wd
       \          /
        B2------B4
    
  • Аналогичным образом, когда вы извлекаете новые изменения из удаленного репо, они обычно являются потомками набора изменений, который является родительским для вашего рабочего каталога, что обеспечивает прямую связь, которая делает возможным объединение незафиксированных изменений:

    --A1----A3----A5---A6---wd
       \          /     \
        A2------A4       A7---A8---A9   (A7 through A9 pulled)
    

Когда Mercurial не объединит незафиксированные изменения:

  • Обновление в той же ветке:

    --A1----A3----A5
       \          /
        A2------A4---A6---wd
    

    Выше были внесены изменения на основе A6 . Если вы обновите до A5 , Mercurial откажется, сообщив либо о «незавершенных незафиксированных изменениях», либо «пересекает ветви». Это потому, что вы пытаетесь объединить незафиксированные изменения из одной головы в другую, и они (по определению) не являются предками или потомками друг друга. Конечно, то же самое происходит с именованными ветвями:

    --A1----A3----A5
       \          /
        B2------B4---B6---wd
    

Обойти это

Существует несколько способов перенести изменения в нового родителя, когда Mercurial не будет автоматически пытаться объединить незафиксированные изменения:

  • Отложить изменения, обновить, затем отменить (ручная обработка конфликтов).
  • Создание патча в MQ будет делать то же самое, так как на полках используются те же патчи, но не очередь из них. Вы обновите патч, откроете его, обновите до другой ветви, а затем отправите патч (ручная обработка конфликтов).
  • Зафиксируйте набор изменений, перебазируйте его в другую ветвь (вам придется пройти через процесс слияния), а затем импортируйте его в MQ, чтобы он больше не был набором изменений, а был патчем.
1 голос
/ 20 августа 2011

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

Таким образом, вы можете обновиться с A на B, если есть способ добраться от A до B, перемещаясь только по родителям или только по детям. E.g.:

 -- A -- 1 -- 2 -- B --

Здесь вы можете обновить данные от A до B и от B до A, потому что они являются потомками и предками друг друга.

 -- A -- 1 -- 2 -- C --
               \
                4 -- B --

Здесь вы также можете обновить с A до B (или с B до A), даже если они находятся в разных ветвях. Однако вы не можете перейти с B на C, потому что для этого вам сначала нужно вернуться назад, а затем вперед.

Обратите внимание, что вы можете обойти это, выполнив маневр назад-вперед самостоятельно:

(on revision B)
$ hg up 2
$ hg up C
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...