Я просто наткнулся на это и наконец понял, что происходит: когда вы обращаетесь к SVN-репозиторию через HTTP и через прокси-сервер , рекомендуемый хук post-commit
запускает svnsync
в фоновом режиме. Фиксация по HTTP заканчивается, как только сервер SVN завершает работу, но перед тем, как прокси-сервер HTTP, который вы читаете, обновляется до новой версии. git-svn
делает коммит, за которым быстро следует выборка и видит устаревший HTTP-прокси без новой ревизии. Предполагается, что он получил новую ревизию и отличается от подсказки пульта с тем, что он пытался зафиксировать, и видит конфликт.
Если вы контролируете конфигурацию прокси-сервера SVN, вы можете сделать svnsync
синхронным (это работало у меня долгое время, пока кто-то не удивил меня изменением конфигурации). В противном случае, я думаю, git-svn
нужен механизм повтора:
diff --git a/git-svn.perl b/git-svn.perl
index 09c4ca5..af9aea1 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -57,6 +57,7 @@ use File::Spec;
use File::Find;
use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;
use IPC::Open3;
+use Time::HiRes qw/usleep/;
use Git;
BEGIN {
@@ -574,7 +575,17 @@ sub cmd_dcommit {
$gs->{inject_parents_dcommit}->{$cmt_rev} =
$parents->{$d};
}
- $_fetch_all ? $gs->fetch_all : $gs->fetch;
+ my $retry;
+ fetch: for ($retry = 0; $retry < 30; ++$retry) {
+ $_fetch_all ? $gs->fetch_all : $gs->fetch;
+ last fetch if ($gs->rev_map_max >= $cmt_rev);
+ # Asynchronous commit push not complete
+ usleep(20000 * ($retry + 1));
+ }
+ if ($retry > 0 && $gs->rev_map_max < $cmt_rev) {
+ fatal "New revision $cmt_rev did not appear",
+ "in repository after $retry retries.";
+ }
$last_rev = $cmt_rev;
next if $_no_rebase;
$
Если это покажется хорошей идеей сегодня вечером, я отправлю патч.
Обновление: при использовании этого я получил:
Author: syncuser <syncuser@d3ff0b4f-3c2c-0410-a809-ba59474314df>
на одном из моих коммитов. Таким образом, все еще может быть состояние гонки, когда сценарий видит частичную синхронизацию. Это раздражает, но не смертельно.