Некоторые сложные слияния подверсии подходят в моем проекте: большие ответвления, которые были независимо в течение долгого времени. Svn дает слишком много конфликтов - и некоторые из них кажутся побочными.
Учитывая, что git
похвалился за превосходящий опыт слияния, Был бы это хорошо работать для использования git-svn
только в пользу создания более управляемого слияния?
Можно ли рекомендовать другие альтернативы (например. svk
, hgsvn
) уменьшить боль слияния?
Некоторые конфликты достаточно легко разрешить (например, импорт Java, пробелы) - таким образом, я также задаюсь вопросом, существуют ли какие-либо автоматические решения для тех.
Полный переключатель к DVCS мог бы произойти в будущем (некоторые из нас любили бы это), но не прямо сейчас. (ОБНОВЛЕНИЕ: это не верно больше - команда, переключенная полностью недавно, и довольно этим).
Заранее спасибо.
PS: существуют сообщения, которые, кажется, связаны (например, мерзавец-svn объединяют 2 ответвления svn), но они не полностью отвечают на этот вопрос.
Обновление: посмотрите мой - ответ новичка после потери работоспособности (и:) эта дорога.
Пытаюсь ответить на мой вопрос: использование 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. Таким образом, это действительно может превратить кошмар в радость, особенно если вам нравится учиться (что в этом случае потребуются некоторые усилия - я думаю, это все равно, что учить мотоцикл после велосипеда).
Несмотря на то, что я не могу заставить всех в компании немедленно переключиться, я действительно не собирался этого делать. Опять же, 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
ой, это слишком долго, остановка пока не поздно .. Удачи.
Я только что сам с этим столкнулся. более простой метод состоит в том, чтобы передать git merge
опцию --squash
, которая будет выполнять слияние без записи фиксации слияния, сохраняя историю линейной, чтобы не запутать git-svn.
Мое слияние тоже было очень большим, и мне пришлось установить git config diff.renamelimit 0
, чтобы git корректно находил все переименования.