Отказ от ответственности: Я обычно делаю , как правило, бегаю git svn rebase
перед выполнением git svn dcommit
. Я обычно храню свои изменения в другой ветке git, чтобы у перебазирования не было шансов на провал. Я использую git rebase master
в своей ветке тем, чтобы обновить его. Затем я переключаюсь на ветку master
и использую git merge
, чтобы включить изменения из моей ветки тем в master
(это перемотка вперед из-за перебазировки).
Мое объяснение ниже объясняет, почему это не нужно механически , но я согласен, что это хорошая идея. Ваши изменения могут не вызывать конфликты с точки зрения различий и слияний, но если вы dcommit
ваш код, не получив последние изменения от svn и не просмотрев их эффекты, вы можете отправить код в svn, который на самом деле не работает правильно.
У вас нет до git svn rebase
до запуска git svn dcommit
. Если изменения, которые вы хотите dcommit, находятся в файлах, которые не изменились в svn с момента последней загрузки изменений, то git-svn не будет отображать конфликт. Таким образом, вы можете вносить изменения в репозиторий svn, используя репозиторий git, в котором нет всех последних изменений из svn.
Допустим, я запускаю svn-репозиторий, содержащий два файла, foo.txt
и bar.txt
. Пока у них только одна ревизия. Я делаю git svn clone
, чтобы начать отслеживать svn-репозиторий с помощью git.
$ git log --oneline --decorate
7e72290 (git-svn, master) Initial commit.
Вы вносите изменения в foo.txt
и git commit
их в свою локальную ветку master
, поэтому она опережает git-svn
.
$ git log --oneline --decorate
aa70eca (master) Added a line to foo.
7e72290 (git-svn) Initial commit.
Чего вы не поняли, так это того, что ваш друг уже внес изменения в bar.txt
как svn revision 2.
Теперь, когда вы запустите git svn dcommit
из master
, git будет искать наборы изменений между тем, где вы находитесь и где остановился git-svn
. В этом случае у вас есть только один: aa70eca
. git пытается отправить этот diff в ваш svn-репозиторий.
$ git svn dcommit
Committing to [svn repo address] ...
M foo.txt
Committed r3
M bar.txt
r2 = 12b95b96e11f782f31b07a78756660cb82437ca2 (refs/remotes/git-svn)
M foo.txt
r3 = d4a7b84e0383f3af5fb0db439169c9f1b8af1152 (refs/remotes/git-svn)
W: aa70ecae4121854ac3754fb882a483b67d706a4a and refs/remotes/git-svn differ, using rebase:
:100644 100644 5771152459bfaa7cc62caa3b6b4d24e52ab8e447 dbfaecb10330d0509e092f1891a4a7e673802413 M bar.txt
First, rewinding head to replay your work on top of it...
Nothing to do.
$ git log --oneline --decorate
d4a7b84 (git-svn, master) Added a line to foo.
12b95b9 Added to bar.
7e72290 Initial commit.
Вы можете видеть, что фиксация прошла успешно как svn revision 3. Когда git-svn затем синхронизировал вашу локальную историю SVN с репозиторием SVN, он получил все новые коммиты , включая изменения, которые вы только что отправили в SVN . Вы заметите, что это изменение (d4a7b84
) имеет хеш SHA, отличный от того, который вы использовали в git (aa70eca
). Это связано с различными причинами: разными временными метками коммитов, потенциально разными именами авторов, git-svn-id
в журнале коммитов, извлеченных из svn, и разными предками & mdash; выбранный svn r3 имеет r2 в качестве родителя, но ваш git коммит произошел от r1.
В этом сценарии был обнаружен diff после выборки между текущей головой git (master
) и SVN, так как содержимое в r2 изменилось foo.txt
. В результате git-svn
будет перебазироваться.
Если я внесу изменение, и в то же время не было никаких других svn коммитов (или я выполнял git svn rebase
, чтобы идти в ногу со временем), то git-svn
не найдет разницу между головой и SVN, поэтому он может просто сбросить:
$ git svn dcommit
Committing to [svn repo address] ...
M foo.txt
Committed r4
M foo.txt
r4 = 533f7337999778628cf39fcd9155d085eb1c2b89 (refs/remotes/git-svn)
No changes between current HEAD and refs/remotes/git-svn
Resetting to the latest refs/remotes/git-svn