Git -svn слияние двух ветвей SVN

Я прочитал многочисленные вопросы и блоги SO на git-svn и слияния. Некоторые из них (особенно git-svn man page) предупреждают об использовании слияния где-нибудь рядом с ветвью, я планирую dcommit из.

Другие, как этот SO ответ, укажите, что слияние прекрасен, пока я использую ветки функций одноразовые, которые я удаляю до dcommitting.

У меня есть установка с двумя длинными SVN (и git) ветвями:

  • trunk (git -svn: svn/trunk, git: master) - стабильная ветвь
  • ветки/девелоп (git -svn: svn/devel, git: devel) - основная ветвь развития, из которой я вилка отключена от ветвей (и я могу жить с возвращая их обратно в devel вместо слияния).

Snapshot of current state in Source Tree

На рисунке выше (1) показывает прошлую историю SVN, где branches/devel был объединен с trunk.

(2) показывает, что я успешно выполнил dcommitted мою текущую разработку в SVN.

Вопрос: Можно ли использовать git-svn для объединения двух ветвей SVN, чтобы история показывала точку слияния (как это может сделать SVN)? Другими словами: что произойдет, если я должен был dcommit из master, как показано в (3)?

Будет ли это испортить мою историю SVN (или git)? Или это просто забудет, что devel вообще не было объединено в master?

EDIT: Если git просто забывает, что devel был объединен с master, существует ли разница между dcommiting от точки (3) и применяя все коммиты как один патч ?

Ответы

Ответ 1

Копаясь в этом вопросе, я обнаружил, что git поддерживает установку свойства svn:mergeinfo в ветке SVN, когда dcommit 'ing:

git svn dcommit --mergeinfo "/branches/somebranch:1-3"

NB! svn:mergeinfo перезаписано тем, что указано в командной строке, поэтому будьте осторожны, чтобы также перечислять предыдущие слияния.

В то время как более новая версия git добавила параметр конфигурации, чтобы автоматически установить это свойство:

config key: svn.pushmergeinfo

У меня возникли проблемы с автоматическим mergeinfo - по какой-то причине или по другой причине git рассчитал его неправильно, и я не смог заставить его работать.

РЕШЕНИЕ: git -merge-svn

Чтобы автоматизировать процесс, я написал оболочку script git -merge-svn, которая может быть использована для объединения двух ветвей SVN с правильным svn:mergeinfo, установленным на dcommit.

script обрабатывает обе ситуации:

  • ветвь не объединена в git - будет делать git merge заранее
  • ветки уже объединены в git (но не в SVN) - будут проходить до предыдущего предка для объединенных изменений совершения.

С помощью этого script я смог произвести эти слияния исключительно на git -side и сохранить информацию о слиянии, так что график git хорошо отображает журнал:

git-merge-svn result

Использование примера:

  • Сделайте некоторые коммиты на devel6
  • dcommit devel6 to SVN ( требуется, чтобы получить номера версий SVN для коммитов)
  • проверить testtunk6 - да, я знаю, что сделал опечатку в названии; -)
  • git merge-svn devel6

Последние commant выходы:

% git merge-svn devel6
About to do an SVN merge: devel6 -> testtunk6

* NEW MERGE COMMIT
|\
| * devel6 [7b71187] (r102)
* | testtunk6 [0682a45] (r101)
 \|
  * [273d6d6] (r100)


STEP 1: GIT merge
Executing:
  git merge devel6

Continue? (y/n) [n]: y
Merge made by the 'recursive' strategy.
 testfile | 1 +
 1 file changed, 1 insertion(+)

STEP 2: SVN dcommit

executing:
git svn dcommit --mergeinfo
/idp/branches/devel:9-32,35-41 /idp/branches/devel6:89 /idp/branches/devel6:94 /idp/branches/devel6:93 /idp/branches/devel6:96 /idp/branches/devel6:97 /idp/branches/devel6:99 /idp/branches/devel6:100 /idp/branches/devel6:102

Continue? (y/n) [n]: y
Committing to https://my.svn.host/svn/auth/idp/branches/testtunk6 ...
  M testfile
Committed r103
  M testfile
Found merge parent (svn:mergeinfo prop): 7b71187fc371d3f86658c5850009e63be88157ac
r103 = 87759323cbadd38bac78087d57b6870a926287e7 (refs/remotes/svn/testtunk6)
No changes between 3fb2168cfbbe605fbd810d76513443203a85a549 and refs/remotes/svn/testtunk6
Resetting to the latest refs/remotes/svn/testtunk6

Ответ 2

Git и Svn имеют другую структуру данных, чтобы сохранить историю.

Svn использует простое дерево. То есть каждая фиксация имеет только одного родителя, но у одного фиксатора может быть несколько дочерних элементов (ветвей). Таким образом, Svn не поддерживает слияния. Вещь, которую они называют "слиянием", на самом деле изменяет портирование, ближайшая аналогия в git составляет rebase или, может быть, cherry-pick. Начиная с версии 1.5 Svn поддерживает свойство metainfo svn:mergeinfo, которое помогает как-то отслеживать, что было "объединено", однако оно выглядит главным образом как обходное решение, объясняющее, почему ветки в Svn настолько трудны в использовании. Точка слияния - это фиксация, которая подавляет все объединенные изменения и разрешение конфликтов в один набор изменений, возможно, аннотированный с помощью свойства svn:mergeinfo.

Git использует Направленный ациклический график, который является очень естественным способом описания слияния и ветвления истории. Точка слияния - это еще одна фиксация с двумя (или более!) Родителями. Таким образом, ваш (3) на картинке является фиксацией слияния. Таким образом, вся история выглядит естественной, все ее цели достижимы на графике истории из текущей точки.

Git -Svn-мосты стараются сделать все возможное, чтобы справиться с недостатком дизайна Svn, прежде чем делать dcommit, он обычно переустанавливает все объединенные коммиты в верхней части текущей ветки Svn. Asof ~ 2 года назад git -svn не смог поставить svn:mergeinfo, поэтому вещь, которую вы просите, невозможна. Более того, когда вы dcommit ing, git создает "близнецовое" сообщение "вряд ли", связанное с фиксацией svn, поэтому он перезаписывает исходную фиксацию.