Как обмануть git-svn, чтобы распознать слияния, сделанные с svn? - PullRequest
5 голосов
/ 02 июня 2009

У нас есть настройка 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. В точке A мы решили объединить изменения из нестабильной ветки в устойчивую ветвь в точке B. Общий предок - это правильно X.

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

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

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

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

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

Ответы [ 4 ]

2 голосов
/ 19 июля 2009

Дополнительной альтернативой может быть использование файла 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

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

commit newparent1 ... newparentN

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

13319a54d3e3d61b501e7cc6474c46f37784aaa3 d99cfccb1f859a8f1dbfac95eec75227fe518b23 31423cd8a838f984547a908777308d846043cbda

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

2 голосов
/ 02 июня 2009

Ваша проблема немного похожа на SVN, заполняющий svnmergeinfo из мерзких слияний в обратном порядке:
Вы не хотите, чтобы SVN записывал слияния из Git, но Git записывал слияния из SVN;)

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

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

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

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

1 голос
/ 16 декабря 2010

Начиная с git 1.6.6, это должно происходить автоматически.

"*" git svn "научился читать SVN 1.5+ и объединять билеты SVK."

в:

http://www.kernel.org/pub/software/scm/git/docs/RelNotes/1.6.6.txt

0 голосов
/ 22 июля 2009

Берегись с файлом прививки ты.

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