Конфликт, отмечающий путаницу при извлечении удаленного файла с помощью darcs - PullRequest
4 голосов
/ 15 ноября 2011

Моя путаница возникает из следующего утверждения , взятого отсюда :

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

Это казалось несовместимым с тем, что я видел, поэтому я создал следующий рабочий процесс, используя darcs 2.5.2:

  1. Создать репо foo;
  2. Создайте непустой файл в foo и запишите его;
  3. Клонировать foo в бар;
  4. Удалите файл в foo и запишите его;
  5. Добавить еще одну строку в файл в строке и записать ее;
  6. Вытащить из foo в бар, получить уведомление о конфликте;

После этих шагов я запустил darcs whatsnew в баре, и мне показали два «примитива патча»:

  1. Блок, удаляющий все «непустые файлы в foo», но без упоминания о строке, добавленной и записанной в bar;
  2. Файл, удаляющий файл.

Мой вопрос: почему нет упоминания о добавленной и записанной строке в строке?

Если я запускаю darcs revert в баре, тогда все имеет смысл: я вижу, что на «непустой файл» не влияет ни один конфликтующий патч, согласно этому утверждению , взятому отсюда :

Команда darcs revert удалит маркировку конфликта и вернет ее в состояние перед конфликтующими патчами.

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


Для справки / воспроизведения вот мой полный рабочий процесс из командной строки:

$ mkdir foo
$ cd foo/
foo$ darcs initialize

foo$ touch shopping
foo$ vi shopping          <-- add a couple of lines
foo$ darcs add shopping

foo$ darcs record 
addfile ./shopping
Shall I record this change? (1/2)  [ynW...], or ? for more options: y
hunk ./shopping 1
+cake
+pie
Shall I record this change? (2/2)  [ynW...], or ? for more options: y
What is the patch name? Added shopping
Do you want to add a long comment? [yn]n
Finished recording patch 'Added shopping'

foo$ cd ..
$ darcs get foo/ bar
$ cd bar/

bar$ vi shopping    <-- add another line
bar$ darcs record 
hunk ./shopping 2
+beer
Shall I record this change? (1/1)  [ynW...], or ? for more options: y
What is the patch name? Added beer
Do you want to add a long comment? [yn]n
Finished recording patch 'Added beer'

bar$ cd ../foo
foo$ rm shopping 
foo$ darcs record 
hunk ./shopping 1
-cake
-pie
Shall I record this change? (1/2)  [ynW...], or ? for more options: y
rmfile ./shopping
Shall I record this change? (2/2)  [ynW...], or ? for more options: y
What is the patch name? Removed shopping
Do you want to add a long comment? [yn]n
Finished recording patch 'Removed shopping'

foo$ cd ../bar
bar$ darcs pull
Pulling from "../foo"...
Mon Nov 14 19:26:44 GMT 2011  dukedave@gmail.com
  * Removed shopping
Shall I pull this patch? (1/1)  [ynW...], or ? for more options: y
Backing up ./shopping(-darcs-backup0)
We have conflicts in the following files:
./shopping
Finished pulling and applying.

bar$ darcs whatsnew 
hunk ./shopping 1
-cake
-pie
rmfile ./shopping

1 Ответ

7 голосов
/ 16 ноября 2011

Если вы запустите darcs changes -v внутри бара, вы увидите историю вашего изменения, в том числе конфликтующий, внесенный в результате вашего перетягивания конфликтующие патчи.

Я обобщил ваш пример на что-то немного более короткое:

DARCS=/usr/bin/darcs

$DARCS init --repo foo
cd foo

echo 'a' > myfile
$DARCS add myfile && $DARCS record -am 'Add myfile'

$DARCS get . ../bar

rm myfile
$DARCS record -am 'Remove myfile'

cd ../bar

echo 'b' >> myfile
$DARCS record -am 'Change myfile'

$DARCS pull -a ../foo

$DARCS changes -v

Теперь, после этого, я вижу этот вывод из darcs changes -v

Tue Nov 15 19:44:38 GMT 2011  Owen Stephens <darcs@owenstephens.co.uk>
  * Remove myfile
    conflictor [
    hunk ./myfile 2
    +b
    ]
    |:
    hunk ./myfile 1
    -a
    conflictor {{
    |:
    hunk ./myfile 2
    +b
    |:
    hunk ./myfile 1
    -a
    }} []
    |hunk ./myfile 1
    |-a
    |:
    rmfile ./myfile

Tue Nov 15 19:44:38 GMT 2011  Owen Stephens <darcs@owenstephens.co.uk>
  * Change myfile
    hunk ./myfile 2
    +b

Tue Nov 15 19:44:38 GMT 2011  Owen Stephens <darcs@owenstephens.co.uk>
  * Add myfile
    addfile ./myfile
    hunk ./myfile 1
    +a

Итак, давайте объясним сумасшедший вывод "Remove myfile". «Удалить мой файл» существует как следующее в foo:

Tue Nov 15 19:44:38 GMT 2011  Owen Stephens <darcs@owenstephens.co.uk>
  * Remove myfile
    hunk ./myfile 1
    -a
    rmfile ./myfile

Итак, кусок в строке 1 и удаление файла.

Вытягивая «remove myfile» в bar, мы модифицируем содержимое патча, вводя специальные примитивы «конфликта», которые представляют примитивы в «Remove myfile», которые конфликтуют с другими примитивами в bar. Нотабене здесь нет потери информации - мы всегда можем вернуться к исходным примитивам, отменив конфликтующие изменения - в этом случае отменив "change myfile".

Конфликторы сбивают с толку, но AFAICT по существу разделяет изменения, которые конфликт с текущим патчем, х в 2 набора: «ix» - это набор патчей, который включает в себя: я) патчи, которые конфликтуют с х и некоторые другие патчи в репо II) патчи, которые конфликтуют с патчем, который конфликтует с х «xx» - это последовательность патчей, которые конфликтуют только с патчем x. Я думаю, что причина этого заключается в том, что Конфликторы имеют эффект «уничтожающие» примитивы, которые вызывают конфликты, но только те, которые не были отменено другим Конфликтором.

Вывод, который мы видим, выглядит примерно так:

"conflictor" ix "[" xx "]" x

Я злоупотребляю обозначениями, но, надеюсь, вы сможете кое-что расшифровать (см. src / Darcs / Patch / V2 / (Real.hs | Non.hs) в репозитории darcs.net для полной истории)

В этом случае «Удалить мой файл» имеет 2 примитивных патча и (в данном случае) 2 соответствующие конфликтующие при извлечении в бар.

Первый примитив (удалить строку 1 из myfile) конфликтует только с примитив в «Изменить myfile» (добавьте «b» в строке 2 myfile), и это первый конфликтор:

conflictor [    <--- The start of xx (no ix here)
hunk ./myfile 2
+b
]               <--- The end of xx
|:
hunk ./myfile 1 <--- x
-a

N.B ("|:" - маркер, который отделяет контекст "не" примитива от сам примитив - я не буду пытаться объяснить это дальше, просто прочитайте ниже |: to см. рассматриваемый примитив)

Второй примитив (удалить myfile) немного сложнее: (rmfile) myfile) конфликтует с (добавьте 'b' в строку 2 myfile), что, как мы знаем, конфликтует с (удалите строку 1 из myfile), поэтому они оба идут в «ix», без патчей в «Хх». Я удалю ненужные разделители "|:" и добавлю пробел:

conflictor {{

hunk ./myfile 2
+b

hunk ./myfile 1
-a

}} 
[]               <--- no xx

|hunk ./myfile 1 <--- start of x
|-a
|:
rmfile ./myfile  <--- end of x

Final (rmfile myfile) имеет некоторый контекст для определения точного примитива. что мы имеем в виду (я не совсем уверен, почему / как это требуется, но мы здесь), который отмечен начальными символами '|' и разделен знаком "|:".

Наконец, попытка объяснить вывод darcs whatsnew в foo; когда конфликт нескольких патчей, я думаю, что фактический эффект конфликта заключается в «отменять» любые конфликтующие патчи, не давая эффекта ни того, ни другого; дает начало некоторым объяснениям: http://en.wikibooks.org/wiki/Understanding_Darcs/Patch_theory_and_conflicts.

Я думаю, что то, что вы видите, является результатом вынужденной коммутации "Изменить мой файл" и "Удалить мой файл", называя их A и B соответственно. Затем, чтобы объединить их, Даркс создает A^-1 и коммутирует A^-1 и B, чтобы дать B' и (A^-1)', где B' имеет эффект A^-1 (так как мы заставляем коммутацию работать ), что означает, что эффект B' (т.е. объединенный «удалить мой файл») на самом деле просто отменяет добавление строки «Изменить мой файл».

У меня не было времени посмотреть, как работает darcs mark-conflicts, поэтому я пока не могу объяснить рабочие изменения, которые вы видите с darcs changes в баре.

...