Требуется ли git svn rebase перед git svn dcommit? - PullRequest
14 голосов
/ 23 апреля 2010

Я читаю об использовании git в качестве svn-клиента здесь:

http://learn.github.com/p/git-svn.html

Эта страница предлагает вам выполнить git svn rebase перед git svn dcommit, что имеет смысл;это похоже на обновление svn перед выполнением svn commit.Затем я начал просматривать документацию для git svn dcommit (мне было интересно, что такое 'd'):

http://git -scm.com / docs / git-svn

Вам нужно немного прокрутить вниз, чтобы увидеть документацию по dcommit, в которой говорится:

Зафиксируйте каждый diff из указанной головы непосредственно в репозиторий SVN, изатем перебазировать или сбросить (в зависимости от того, есть ли разница между SVN и головой) .

Это смущает меня, потому что, если вы сделаете, как сказано на первой странице, не будетизменения, выпадающие из svn после завершения первой части dcommit.

Меня также смущает часть, которая говорит о перезагрузке;не git reset для удаления изменений из области подготовки?

Зачем перебазировать или сбрасывать после (первой части) dcommit?

1 Ответ

19 голосов
/ 23 апреля 2010

Отказ от ответственности: Я обычно делаю , как правило, бегаю 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
...