Используя мерзавца-svn (или подобный) *просто* для выручения со слиянием svn?

Некоторые сложные слияния подверсии подходят в моем проекте: большие ответвления, которые были независимо в течение долгого времени. Svn дает слишком много конфликтов - и некоторые из них кажутся побочными.


Учитывая, что git похвалился за превосходящий опыт слияния, Был бы это хорошо работать для использования git-svn только в пользу создания более управляемого слияния?


Можно ли рекомендовать другие альтернативы (например. svk, hgsvn) уменьшить боль слияния?

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

Полный переключатель к DVCS мог бы произойти в будущем (некоторые из нас любили бы это), но не прямо сейчас. (ОБНОВЛЕНИЕ: это не верно больше - команда, переключенная полностью недавно, и довольно этим).

Заранее спасибо.

PS: существуют сообщения, которые, кажется, связаны (например, мерзавец-svn объединяют 2 ответвления svn), но они не полностью отвечают на этот вопрос.

Обновление: посмотрите мой - ответ новичка после потери работоспособности (и:) эта дорога.

27
задан Community 23 May 2017 в 11:43
поделиться

2 ответа

Пытаюсь ответить на мой вопрос: использование git для слияния svn кажется многообещающим.

Обновление: это не просто многообещающе, это большой успех. Короче говоря, Линус был прав .

Только что завершено огромное слияние двух веток svn, которые были разделены в течение 1,5 лет; Было изменено 3k файлов, получилось множество конфликтов в svn (кажется, ~ 800).

Я нашел git & git-svn спасателем жизни:

  • разрешение автоконфликтов: для начала, это дало намного меньше конфликтующих файлов (~ половина, я думаю)
  • невероятная производительность
  • отличная репо / модель ветвления , гибкие рабочие процессы: легкое экспериментирование с различными подходами, такими как слияние по частям (по времени), постоянная проверка работоспособности (компиляция и т. д.); всякий раз, когда возникает проблема: просто отступайте. Вы всегда можете сделать шаг назад, когда это необходимо.
  • удобство использования, отличный инструментарий:
    • git-log (и соответствующие параметры git-rev-parse ), нет ничего более мощного, чем это. Это также удобно: -p дает вам различия за один раз; в svn вы получаете журнал, а затем находите разницу для этой «ревизии-1: ревизия» или используйте неуклюжие пользовательские интерфейсы. Найти, когда строка была добавлена ​​/ удалена в репо, одновременный поиск в нескольких ветвях
    • gitk : чрезвычайно полезен для визуализации истории ветвей в сочетании с отличными возможностями поиска. Не встречал ничего подобного в других инструментах, особенно не так быстро, как этот. Неважно, что это в Tk, это просто великолепно
    • git gui : отлично работает, даже если не самое сексуальное - отличный помощник для новичков в обнаружении вещей
    • виноват : чудо. Да, он определяет, откуда берется исходный сегмент (копирование и вставка и т. Д.)
    • mergetool : гораздо приятнее, чем запуск большого svn merge , который затем останавливается каждый раз (т.е. каждые 5 минут) при возникновении конфликта нажмите «(p) ostpone», а затем вручную найдите конфликтующие файлы. Предпочитаемый вариант этого интегрирован в git gui (для этого требовался крошечный патч ). Установлено, что интеграция внешних инструментов сравнения лучше настраивается, чем в svn .
    • подключаемые драйверы слияния и мелкозернистый контроль над ними
    • rebase позволяет отфильтровывать беспорядочные части истории svn.
  • распределение: не нужно приходить в офис, когда работаешь над этим, может приостанавливаться и прогресс пошагово на поезде / самолете и т. д.
    • USB-накопитель с Unison сделал синхронизацию <-> проще простого
    • это было бы невозможно без сумасшедшего сжатия git (проект 5-летней давности с 26k коммитов, тонны ветки и двоичные файлы, багажная svn checkout: 1,9 ГБ => все это в полном репозитории git: 1,4 ГБ!)

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

Несмотря на то, что я не могу заставить всех в компании немедленно переключиться, я действительно не собирался этого делать. Опять же, git-svn спасает нас тем, что мы «сначала опускаем ногу». Но, видя реакцию коллег, переключение может произойти намного раньше, чем кто-либо ожидал :)

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

Предостережение:

«Не dcommit Git слияние коммитов на репозиторий Subversion. Subversion не обрабатывает слияния одинаково как Git, и это вызовет проблемы. Это означает, что вы должны сохранить свой Git история развития линейная (т.е. нет слияние из других веток, просто перебазирование) ". (последний абзац http://learn.github.com/p/git-svn.html )

Еще один отличный источник - книга Pro Git , в разделе «Переключение активных ветвей» в основном говорится, что слияние действительно работает, но dcommit сохранит только контент слияния, но история будет скомпрометирована (что нарушит последующие слияния), поэтому вам следует удалить рабочую ветвь после слияния. В любом случае, в конце концов, это имеет смысл, и на практике здесь легко избежать ловушек ... в svn я обнаружил, что люди обычно не объединяются повторно, поэтому это можно рассматривать только как шаг назад, если вы пришли из мира git в первом место.

Как бы то ни было, dcommit просто сработал для меня.Я сделал это на своей собственной ветке svn workbranch, которую оставил только для этого, поэтому в тот раз избегал дополнительных конфликтов. Однако я решил сделать окончательное слияние из этой ветки в svn trunk в svn (после синхронизации всего в git); - ignore-ancestry дал лучшие результаты там.

Обновление: как я узнал позже, последних нескольких шагов выше (дополнительное ветвление svn и слияние - ignore-ancestry) легко избежать, просто сохранив ветвь, которую вы создаете, из линейной. Как говорит Гейб ниже, merge --squash просто создает простой глупый коммит, дружественный к svn. Когда я буду готов к огромным слияниям в моей локальной ветке (что может занять дни / недели), я бы просто:

git checkout -b dcommit_helper_for_svnbranch  svnbranch
git merge --squash huge_merge_work_with_messy_nonlinear_history
git commit 'nice merge summary' # single parent, straight from the fresh svnbranch
git dcommit

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


ОБНОВЛЕНИЕ : @Kevin запросил более подробную информацию обо всем процессе слияния веток svn .. Там много статей, сообщений, но как новичок я обнаружил некоторые запутанные / вводящие в заблуждение / устаревшие. .В любом случае, как я это делаю сейчас (конечно, застрял с git-svn после того случая слияния; как и некоторые недавно инфицированные коллеги) ..

git svn clone -s http://svn/path/to/just-above-trunk  # the slowest part, but needed only once ever..you can every single branch from the svn repo since revision #1. 2) 
git svn fetch          # later, anytime: keep it up to date, talking to svn server to grab new revisions. Again: all branches - and yet it's usually a faster for me than a simple 'svn up' on the trunk:)    
# Take a look, sniff around - some optional but handy commands:
git gui   &    # I usually keep this running, press F5 to refresh
gitk --all     # graph showing all branches
gitk my-svn-target-branch svn-branch-to-merge    # look at only the branches in question
git checkout -b my-merge-fun my-svn-target-branch  # this creates a local branch based on the svn one and switches to it..before you notice :)
# Some handy config, giving more context for conflicts
git config merge.conflictstyle diff3
# The actual merge.. 
git merge  svn-branch-to-merge    # the normal case, with managable amount of conflicts
# For the monster merge, this was actually a loop for me: due to the sheer size, I split up the 2 year period into reasonable chunks, eg. ~1 months, tagged those versions ma1..ma25 and mb1..mb25 on each branch using gitk, and then repeated these for all of them
git merge ma1   # through ma25
git merge mb1   # through mb25
# When running into conflicts, just resolve them.. low tech way: keep the wanted parts, then "git add file" but you can
git mergetool   # loops through each conflicted file, open your GUI mergetool of choice..when successful, add the file automatically.
git mergetool  my-interesting-path # limit scope to that path

На самом деле я предпочел использовать встроенную интеграцию с mergetool 'git gui (щелкните правой кнопкой мыши в файле, находящемся в конфликте). Однако это немного ограничено, поэтому см. Мой небольшой патч выше, который позволяет вам подключить сценарий оболочки, в котором вы можете вызывать любые инструменты слияния, которые вы предпочитаете (иногда я пробовал несколько из них параллельно, так как они вызывали удивительное количество проблем ... но обычно Я застрял с kdiff3 ..

Когда этап слияния проходит нормально (нет конфликта), фиксация слияния выполняется автоматически; в противном случае вы разрешаете конфликты, затем

git commit  # am usually doing this in the git gui as well.. again, lightning fast.

Последняя фаза. Обратите внимание, что до сих пор у нас были только локальные коммиты, а не связь с svn-сервером. Если вы не использовали --squash или другие уловки, теперь у вас будет график, в котором у вашего коммита слияния есть два родителя: кончики ветвей svn-mirror. Теперь это обычная ошибка: svn может принимать только линейную историю ... так что git-svn упрощает его, просто отбрасывая второго родителя (svn-branch-to-merge в приведенном выше случае) .. так что реальное отслеживание слияния перешел на сторону svn .. но в остальном в этом случае все нормально.

Если вам нужен более безопасный / чистый способ, здесь пригодится мой предыдущий фрагмент: просто выполните окончательное слияние с --squash. Адаптировал предыдущий к этому потоку:

git checkout -b dcommit_helper_for_svnbranch my-svn-target-branch  # another local workbranch.. basically needed as svn branches (as any other remote branch) are read-only
git merge --squash my-merge-fun  
git commit 'nice merge summary' # single parent, straight from the fresh svn branch
git dcommit  # this will result in a 'svn commit' on the my-svn-target-branch

ой, это слишком долго, остановка пока не поздно .. Удачи.

34
ответ дан 28 November 2019 в 05:26
поделиться

Я только что сам с этим столкнулся. более простой метод состоит в том, чтобы передать git merge опцию --squash, которая будет выполнять слияние без записи фиксации слияния, сохраняя историю линейной, чтобы не запутать git-svn.

Мое слияние тоже было очень большим, и мне пришлось установить git config diff.renamelimit 0, чтобы git корректно находил все переименования.

3
ответ дан 28 November 2019 в 05:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: