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, поэтому он перезаписывает исходную фиксацию.