Используя Subversion, как я могу вырезать из одного файла и вставить в другой, сохраняя историю

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

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

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

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

В основном я использую TortoiseSVN, но у меня также установлена ​​Subversion командной строки.

13.10.2009 00:27:03
4 ОТВЕТА
РЕШЕНИЕ

Вы можете объединить все ревизии (или конкретные ревизии) одного файла в другой, как это

svn merge sourcefile targetfile -r 0:HEAD

Сначала я подумал, что нужно будет использовать эту --ignore-ancestryопцию (поскольку оба файла не имеют общей истории), но, видимо, в этом нет необходимости. Я тестировал с SVN 1.6.3.

Конечно, вы можете получить много маркеров конфликтов в результате слияния. Может быть проще выполнить слияние вручную (слияние копирования и вставки, как вы говорите), а затем выполните указанную выше команду слияния с, --record-onlyчтобы сообщить об этом Subversion.

После слияния объект targetfileбудет иметь svn:mergeinfoсвойство, которое указывает, какие коммиты sourcefileоткуда слились в него. Когда вы просматриваете журнал targetfile, вы можете увидеть историю обоих файлов, используя --use-merge-historyопцию. TortoiseSVN имеет такую ​​же функцию в виде флажка в форме журнала.

17
14.10.2009 17:45:25
Я подозреваю, что это не совсем то, что я хочу, но я уверен, что это лучшее, что я получу (не считая svn dump hacking), поэтому я принимаю. Спасибо.
Steve314 13.10.2009 16:59:40
У вас будет журнал фиксации, но все строки в ваших изменениях будут иметь одинаковый маркер ревизии в «винить».
Xavier Nodet 14.10.2009 15:27:57
вау, я исправлюсь Думаю, я не очень знаком с новыми функциями отслеживания слияний. Я думаю, что это будет работать только на SVN 1.5+ (может быть, 1.6+).
Ken Liu 16.10.2009 04:46:27

Если вы хотите скопировать в новый файл и удалить старый файл:

svn mv

Если вы хотите скопировать в новый файл:

svn copy

Если оба файла уже существуют:

# copy/paste with a text editor

Вы можете удалить файл и сохранить его историю:

svn del

С SVN вы не можете отслеживать историю слияния двух файлов. Вы можете объединить его вручную и сохранить след в сообщении фиксации.

1
13.10.2009 01:26:31
Ни один из них не дает мне файл, содержащий текст (и историю) из двух исходных файлов. Текстовый редактор copy / paste сохраняет историю из обоих хранилищ, правда - ничего не удаляется, но история из файла, из которого вы вырезали, отделена от файла, в который вы вставили. С точки зрения TortoiseSVN, Blame будет винить во всем не только тех, кто принимал решения по кодированию.
Steve314 13.10.2009 00:53:39
Это все инструменты, которые предоставляет вам Subversion. Вы, вероятно, должны использовать некоторые DVCS. TortoiseMercurial существует для пользователей Windows.
Natim 13.10.2009 01:06:24
Кстати, я не совсем понимаю, что вы ожидаете от объединения истории двух файлов. это не имеет смысла. Какой откат ты имеешь в виду? Вы можете добавить комментарий в начале вашего файла, чтобы сказать, что это слияние этого файла и другого в ревизии rXXXX
Natim 13.10.2009 01:08:34
Откат не проблема. Речь идет о отслеживании дизайнерских решений. Журнал представляет собой отличную проектную документацию, объясняющую, почему вы приняли решения, которые приняли. Возможность просматривать различия между версиями или видеть, почему каждая строка была изменена в последний раз, неоценима.
Steve314 13.10.2009 01:44:36
Это, конечно, потребует некоторой дисциплины со стороны каждого, но я думаю, что добавление содержательных комментариев к коммитам, объясняющих, почему вы вносили изменения каждый раз, поможет при извлечении журнала.
Critical Skill 13.10.2009 04:21:15

Я не думаю, что вы можете сохранить историю так, как вы описываете. SVN отслеживает историю в отдельности и не отслеживает два отдельных файла, которые объединены в одной строке кода.

Если вы начали с двух отдельных файлов, а затем объединили их в третий, то история обоих будет сохранена. Если вы объедините одно в другое, то история одного из них будет «утеряна» в том смысле, что вы не сможете ссылаться на историю «удаленного» файла, просто взглянув на историю.

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

4
13.10.2009 01:11:31
У меня было чувство, что это был ответ. Еще не принято по случайности - завтра я еще посмотрю на всякий случай.
Steve314 13.10.2009 01:31:40

Разве вы не можете оставить код в своем собственном файле (после обрезки частей, которые вы не хотите сохранять) и включить этот файл в свой «настоящий» исходный файл?

// file foo.cpp:
...
namespace {
#  include "util_code.inc"
}

Не совсем православный, но должен работать ...

-1
13.10.2009 17:09:03
Мне не нравится этот стиль использования #include. Давным-давно привыкли к соглашениям «это то, что есть спецификация, то, что есть тело» на других языках. Наверное, поэтому эта идея даже не пришла мне в голову - но, думаю, это не так уж и плохо, учитывая целый ряд несовершенных решений. Слишком поздно на этот раз - но всегда есть следующий раз.
Steve314 15.10.2009 08:58:25
Спасибо. Конечно, я бы не рекомендовал использовать такие директивы #include. Но я использовал их, чтобы включить сгенерированный код: #define THE_CLASS MyClass #include method_bodies.inc с method_bodies.inc, похожим на это: void THE_CLASS :: generateMethod () {...} Таким образом, я смог сгенерировать некоторые, но не все методы класса без генератора, знающего имя класса.
Xavier Nodet 15.10.2009 09:23:29