Частичные коммиты с помощью Subversion

104

В данном случае я внес два независимых изменения в один файл: например. добавил новый метод и изменил другой метод.

Я часто хочу фиксировать оба изменения не как одну фиксацию, а как две независимые фиксации.

На репозиторий я хотел бы использовать в интерактивном режиме из GIT-дополнения (1) , чтобы разделить кусок на более мелкие:

 git add --patch

Какой самый простой способ сделать это с помощью Subversion? (Возможно, даже с использованием подключаемого модуля Eclipse)

Обновление:
в The Thing About Git Райан называет это: «Запутанная проблема рабочей копии».

Бенедикт Вальдфогель
источник
Вы искали решение именно в командной строке? Во многих из приведенных ниже ответов упоминается TortoiseSVN «восстановление после фиксации», которое является функцией только для Tortoise, то есть для графического интерфейса и для Windows.
florisla

Ответы:

35

С помощью git-svn вы можете создать локальный репозиторий GIT для удаленного репозитория SVN, работать с ним, используя полный набор функций GIT (включая частичные коммиты), а затем отправить все это обратно в репозиторий SVN.

git-svn (1)

Jkramer
источник
25
В этом решении есть особая ирония.
tuxayo
65

Tortoise SVN 1.8 теперь поддерживает это с помощью функции «Восстановить после фиксации». Это позволяет вам вносить изменения в файл, причем все изменения отменяются после фиксации.

Согласно документации:

Чтобы зафиксировать только те части файла, которые относятся к одной конкретной проблеме:

  1. в диалоговом окне фиксации щелкните файл правой кнопкой мыши и выберите «восстановить после фиксации»
  2. отредактируйте файл, например, в TortoiseMerge: отмените изменения, которые вы еще не хотите фиксировать
  3. сохраните файл
  4. зафиксировать файл
Casebash
источник
Интересно, как это работает. Я проверил примечания к выпуску SVN 1.8 , но не могу понять, на чем основана функция «Восстановление после фиксации».
DavidS
3
@DavidS Это не функция SVN. Это особенность TortoiseSVN.
florisla
К вашему сведению, SVN 1.8 - это EOL с апреля 2018 года с выпуском 1.10
Грег К.
Мы также можем найти его в документации здесь: tortoisesvn.net/docs/release/TortoiseSVN_en/…
Гийом
42

Я сделал это с помощью TortoiseSVN .

Встроенная утилита слияния позволяет вам показать разницу между версией репозитория и вашей рабочей копией.

Используйте функцию создания резервной копии утилиты diff

  1. Перейдите к фиксации файла, как если бы вы собирались зафиксировать все свои изменения.
  2. В окне фиксации дважды щелкните файл, чтобы отобразить разницу.
  3. В настройках различий выберите вариант резервного копирования исходного файла .
  4. Щелкните правой кнопкой мыши нежелательные изменения и используйте select, используйте другой текстовый блок .
  5. Сохраните разницу ровно один раз . Резервная копия будет перезаписываться каждый раз при сохранении. Вот почему вы хотите сэкономить только один раз.
  6. Зафиксируйте изменение.
  7. Замените оригинал созданным файлом .bak (который будет содержать все ваши исходные изменения).
  8. Зафиксируйте свой файл.

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

Спайк
источник
1
Как именно вы это сделали? Мне было бы интересно изучить эту технику.
Лассе В. Карлсен
Было бы так здорово, если бы это автоматически перезаписывалось файлами .bak после фиксации.
BCS
Я не нашел шаг 3: вариант резервного копирования с использованием Tortoise SVN 1.8.1
sudhAnsu63
4
Неважно. Найдена соответствующая ссылка для 1.8 tortoisesvn.net/tsvn_1.8_releasenotes.html Чтобы зафиксировать только те части файла, которые относятся к одной конкретной проблеме: в диалоговом окне фиксации щелкните файл правой кнопкой мыши, выберите «Восстановить после фиксации», отредактируйте файл в, например, TortoiseMerge: отменить изменения, которые вы не хотите фиксировать, но сохранить файл, зафиксировать файл
sudhAnsu63
К сожалению, в Tortoise версии 1.8.5 это недоступно, как и «восстановление после фиксации».
kajaco
24

Попробуйте использовать, svn diff > out.patchзатем скопируйте out.patchфайл в out.patch.addиout.patch.modify

Только если у вас есть рабочий файл патча, верните исходный файл, используя svn revert out.c.

Отредактируйте файлы патчей вручную, чтобы они содержали только блоки для добавления или изменения. Примените их к исходному файлу с помощью patchкоманды, проверьте, сработало ли добавление, затем svn commitдобавление.

Повторение промывки и полоскания для out.patch.modifyпластыря.

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

Это очень утомительное решение, хотя я не уверен, что у вас должна быть причина для разделения ваших коммитов.

Вы также могли проверить несколько рабочих копий одного и того же источника, чтобы применить свою работу к:

svn co http://location/repository methodAdd

svn co http://location/repository methodModify

Обязательно проверьте svn upи убедитесь, что все в порядке.

Крис
источник
11

Это возможно с помощью TortoiseSvn (Windows) начиная с версии 1.8.

4.4.1. Диалог фиксации

Если ваша рабочая копия обновлена ​​и нет конфликтов, вы готовы зафиксировать свои изменения. Выберите любой файл и / или папки, которые вы хотите зафиксировать, затем TortoiseSVN → Зафиксировать ....

<снип>

4.4.3. Зафиксировать только части файлов

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

Щелкните правой кнопкой мыши файл и выберите Контекстное меню → Восстановить после фиксации. Это создаст копию файла как есть. Затем вы можете отредактировать файл, например, в TortoiseMerge, и отменить все изменения, которые вы не хотите фиксировать. После сохранения этих изменений вы можете зафиксировать файл.

После завершения фиксации копия файла восстанавливается автоматически, и у вас есть файл со всеми вашими изменениями, которые не были зафиксированы обратно.

В Linux я бы попробовал http://webstaff.itn.liu.se/~karlu20/div/blog/2013-05-31_SVNPartialCommit.php . Хотя сам еще не пробовал.

парвус
источник
8

Раньше я так делал:

  • В моем редакторе (я использую vim) отредактируйте файл так, чтобы отображалось только одно из изменений
  • Сохраните файл (но не выходите из редактора)
  • Зафиксируйте измененный файл в svn
  • Нажмите «Отменить» в редакторе столько раз, чтобы второй набор изменений снова появился
  • Сохраните файл еще раз
  • Зафиксируйте второй набор изменений.

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

Теперь, когда я использую git, надеюсь, мне больше никогда не придется это делать!

Грег Хьюгилл
источник
4

Я использую либо локальное репо darcs, либо просто постепенно сливаю изменения. С помощью слияния (opendiff открывает FileMerge, программу слияния, которая поставляется с Xcode; замените вашим любимым инструментом слияния):

cp file file.new
svn revert file
opendiff file.new file -merge file

объединить связанные изменения, сохранить объединение, выйти из программы объединения

svn ci -m 'first hunk' file
mv file.new file
svn ci -m 'second hunk' file

если в файле более одного несвязанного фрагмента, промойте и повторите (но зачем вам так долго ждать перед фиксацией ?!)

Кроме того, если вы знаете git, вы можете использовать git-svn для поддержки локального репозитория git и синхронизации ваших коммитов с главным сервером svn; отлично работает в моем ограниченном опыте.

Эон
источник
9
Re: "Зачем ждать так долго?" Вы целый день занимаетесь большим рефакторингом, а босс перед обедом выкидывает небольшую ошибку «исправить сейчас».
BCS,
4

Попробуйте VisualSVN для Visual Studio . В последней версии 6.1 представлена ​​функция QuickCommit. Вы можете частично зафиксировать выбранные изменения в файле с помощью новых команд контекстного меню « Зафиксировать этот блок» и « Зафиксировать выделение» в редакторе Visual Studio.

введите описание изображения здесь

бахреп
источник
2
  1. Откройте все файлы, которые хотите разделить, в любом редакторе.
  2. Используя другой набор инструментов (в Win используйте предложение Спайка (старая версия)), верните второй набор.
  3. Зафиксировать
  4. вернитесь к выбранному вами редактору и сохраните все файлы

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

БКС
источник
0

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

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

Ян Данн
источник
0
  1. Скопируйте все соответствующие измененные файлы в резервные копии.
  2. Создайте патч рабочего состояния с помощью svn diff.
  3. Верните файлы, используя svn revert.
  4. Повторно примените части патча, которые вы хотите зафиксировать, либо с помощью patchинструмента, либо путем ручного редактирования, или как-то еще.
  5. diffПосле этого запустите, чтобы сравнить вашу рабочую копию с резервной копией, чтобы убедиться, что вы правильно применили патч-части.
  6. Сборка и тестирование.
  7. Зафиксировать.
  8. Скопируйте резервные копии обратно в хранилище для извлечения.
  9. Повторяйте на 2. (не на 1.!), Пока не будете готовы.
michaeljt
источник