2009-06-02 2 views
5

У нас есть установка SVN со стабильной магистралью и нестабильной ветвью развития. Работа Dev (в основном) выполняется на ветке, а затем до развертывания объединена с магистралью.Как обмануть git-svn, чтобы распознать слияния, сделанные с помощью svn?

Я использую git-svn в качестве моего SVN-клиента. Мой процесс слияния с неустойчивым к стволу выглядит следующим образом:

git svn fetch 
git co -b trunk svn/trunk 
git merge --no-ff svn/unstable 
git svn dcommit 

svn/* являются удаленные ветви SVN.

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

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

И вот это руб. Когда кто-то делает слияние, git не знает об этом. Ниже приведен пример:

o-...-A---o---C--- unstable 
/
X--...--B---o---o--- stable 

Неустойчивая ветвь была создана в точке X. В точке А мы решили объединить изменения из-за нестабильной ветки в стабильную ветвь в точке В. Общий предок правильно Х.

Поскольку слияние не записано в истории git, следующее слияние в C снова предполагает, что X является общим предком. Я хотел бы он быть, как в следующем графике:

o-...-A---o---C--- unstable 
/  \ 
X---...---B---o---o--- stable 

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

У меня есть некоторые варианты в виду, например, правильное использование ветви git-filter или "фальшивого" фиксации, которое никогда не будет отдано SVN. Однако ни одна из моих попыток до сих пор не работала.

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

ответ

2

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

Это означает, что после того, как вы увидите слияние в репозитории SVN, вам просто нужно добавить строку в .git/info/grafts с помощью SHA-1 слияния (M) и его родителей (A, B).

 o-...-A---o---D--- unstable 
    /  
    X-----B---M---o---o--- stable 

A = 31423cd8a838f984547a908777308d846043cbda 
B = d99cfccb1f859a8f1dbfac95eec75227fe518b23 
M = 13319a54d3e3d61b501e7cc6474c46f37784aaa3 

Чтобы создать ссылку с утра, вы должны указать родитель M, как B и A. Формат файла черенков довольно прост:

commit newparent1 ... newparentN 

Это означает, что вы добавить следующее (довольно долго) линии ваших трансплантатов файл:

13319a54d3e3d61b501e7cc6474c46f37784aaa3 d99cfccb1f859a8f1dbfac95eec75227fe518b23 31423cd8a838f984547a908777308d846043cbda 

Git теперь будет делать вид, что это на самом деле произошло слияние. Как недостаток, это не распространяется через git push/fetch/clone, но это не должно быть серьезной проблемой для личного развития.

+0

Спасибо! Это первый раз, когда я слышал о трансплантатах. Всегда хорошо учиться больше. –

2

Ваша задача немного напоминает SVN populating svnmergeinfo from git merges в обратном направлении:
Вы не хотите SVN записывать слияния с Git, но Git для записи сливается с SVN;)

Поскольку git-svn не заботится о svnmergeinfo атрибут при импорте из SVN, которые оставляют опцию «ручной режим».

Я бы не рекомендовал решение git-filter-branch или что-нибудь, что переписывает историю на стороне Git.
Если вам известно о слиянии «A->B» на SVN, вы должны сделать это слияние на Git ** в ветке «merge», а затем объединить его обратно в устойчивую ветвь (тривиальное слияние в этой точке), таким образом добавив новую фиксацию в вашу текущую стабильную историю.

o-.....-A---o---C--- unstable 
/  \ 
/   o-------\__ merge recorder branch 
/  /  \ 
X---.....---B---o---o---o__ stable 

Тогда слияние от C к конюшне должно иметь A как общий предок.

+0

Правильно! Таким образом, ключ состоит в том, чтобы сделать _two_ посреднические коммиты, один из которых также попадает в SVN. Кажется, это работает, по крайней мере, на бумаге. Спасибо за информацию! Интересно, можно ли сжать это в псевдоним git ... –

+0

Вы забыли закончить свой «**» (полужирный) в «... Git ** в ветке« merge »...» –

0

Остерегайтесь с помощью прививок.

  1. ли их неправильно и мерзавец дс будет (через некоторое время) падение частей истории
  2. Если нажать на другой хост, он не будет знать о трансплантатах и ​​может в конечном итоге с разбитой историей.