Я пытаюсь использовать git поверх старого репозитория subversion. У нас есть несколько пользователей, работающих с новым git remote (origin/master), который является git svn-клоном более старого репо. Проблема заключается в том, что мы делаем git svn dcommit, чтобы переместить изменения из нового репозитория git в старый репозиторий subversion, имя пользователя commiter потеряно и вместо этого заменено на пользовательскую информацию git svn clone'd. Есть ли способ сохранить информацию комминера в subversion на dcommit?
Git svn dcommit с svn именами пользователей
Ответ 1
Вы можете использовать git -svn с --add-author-from
и --use-log-author
. Первая представляет автора git в строке From:
в сообщении о фиксации, последний выполняет обратное преобразование.
Тем не менее, форматы репозитория имеют значение, а формат репозитория subversion хуже, чем git. Он не поддерживает слияние хорошо, или коммиттеры против авторов, или время фиксации, отличное от времени нажатия. git -svn в порядке, чтобы локально получить git ui, но он не может сильно повлиять на модель данных. Надеемся, вы сможете перейти в репозиторий git, возможно, с помощью svn frontend (сейчас есть git -svnserver и github с закрытым исходным кодом).
Ответ 2
Я знаю, что это очень старая тема, но если кому-то интересно, я добавил этот хак в свою локальную копию git -svn:
23a24
> use POSIX qw/strftime/;
984a986
> my $ra = Git::SVN::Ra->new($url);
987c989
< ra => Git::SVN::Ra->new($url),
---
> ra => $ra,
995a998,1014
> my $cmt_author = get_commit_entry($d)->{author};
> my $cmt_date = get_commit_entry($d)->{date};
> if ( defined $cmt_author ) {
> foreach my $key ( keys %users ) {
> my $i = index($cmt_author, $users{$key}[1]);
> if ( $i != -1 ) {
> print "Changed author to $key\n";
> $ra->change_rev_prop($cmt_rev, 'svn:author', $key);
> last;
> }
> }
> }
> if ( defined $cmt_date ) {
> $cmt_date = strftime("%Y-%m-%dT%H:%M:%S.000000Z", gmtime($cmt_date));
> print "Changed date to $cmt_date\n";
> $ra->change_rev_prop($cmt_rev, 'svn:date', $cmt_date);
> }
1758c1777
< my %log_entry = ( log => '', tree => get_tree_from_treeish($treeish) );
---
> my %log_entry = ( log => '', tree => get_tree_from_treeish($treeish), author => undef, date => undef );
1768a1788
> my $date;
1774c1794,1797
< $author = $1 if (/^author (.*>)/);
---
> if (/^author (.*>) (\d+) ([\-\+]?\d+)$/o) {
> $author = $1;
> $date = Git::SVN::Log::parse_git_date($2, $3);
> }
1792a1816,1817
> $log_entry{author} = $author || undef;
> $log_entry{date} = $date || undef;
Это против 1.9.1-1 (версия пакета deb на Ubuntu 14.04). Он не настраивается, в том смысле, что если у вас есть файл users.txt, он будет использовать его, и он всегда будет пытаться установить дату. Также, если у вас есть несколько учетных записей SVN для данного пользователя git, он просто выберет один.
И я только начинаю использовать его в гневе, но я думаю, что это может сработать, скрестив пальцы!
Отношения Адам
Ответ 3
Я немного изменил патч, предложенный Adam Sutton, чтобы git svn dcommit
принял --commit-author
вариант:
--- ./git-svn.orig 2014-10-09 23:11:40.032767542 +0300
+++ ./git-svn 2014-10-09 23:27:58.252753020 +0300
@@ -116,7 +116,7 @@
$_before, $_after,
$_merge, $_strategy, $_preserve_merges, $_dry_run, $_parents, $_local,
$_prefix, $_no_checkout, $_url, $_verbose,
- $_commit_url, $_tag, $_merge_info, $_interactive);
+ $_commit_url, $_commit_author, $_tag, $_merge_info, $_interactive);
# This is a refactoring artifact so Git::SVN can get at this git-svn switch.
sub opt_prefix { return $_prefix || '' }
@@ -194,6 +194,7 @@
'dry-run|n' => \$_dry_run,
'fetch-all|all' => \$_fetch_all,
'commit-url=s' => \$_commit_url,
+ 'commit-author=s' => \$_commit_author,
'revision|r=i' => \$_revision,
'no-rebase' => \$_no_rebase,
'mergeinfo=s' => \$_merge_info,
@@ -982,6 +983,7 @@
$rewritten_parent);
}
+ my $ra = Git::SVN::Ra->new($url);
my %ed_opts = ( r => $last_rev,
log => get_commit_entry($d)->{log},
ra => $ra,
@@ -993,6 +995,10 @@
editor_cb => sub {
print "Committed r$_[0]\n";
$cmt_rev = $_[0];
+ if (defined($_commit_author)) {
+ print "Changed author to $_commit_author\n";
+ $ra->change_rev_prop($cmt_rev, 'svn:author', $_commit_author);
+ }
},
mergeinfo => $_merge_info,
svn_path => '');
@@ -1790,6 +1796,7 @@
}
print $log_fh $msgbuf or croak $!;
command_close_pipe($msg_fh, $ctx);
+ $log_entry{author} = $author || undef;
}
close $log_fh or croak $!;
Ответ 4
Требовать от всех использовать "подписанный" или другой способ включить свое имя пользователя в сообщение каждой фиксации. Это довольно уродливое решение, но AFAIK - единственное, что вы можете сделать без взлома источника git -svn.
Ответ 5
Это еще одна слегка измененная версия от Адама Саттона. Он создает обратное отображение из файла авторов и выполняет дополнительную проверку для дубликатов и/или отсутствующих авторов. Он также сообщает вам о том, что пользователь Git был сопоставлен с каким SVN-пользователем для каждой фиксации, даже при запуске Git svn dcommit -dry-run.
[[email protected] git-svn-bridge]# diff scripts/git-svn.orig scripts/git-svn.hacked
23a24
> use POSIX;
963a965,975
>
> #Revert the keys/values from authors into a reverse map.
> #If a duplicate is found(i.e. 2 git users matching 1 svn user) abort the operation.
> my %rev_author_map;
> while (my ($key, @value) = each %users) {
> my $rev_key="$value[0][0] <$value[0][1]>";
> if(exists $rev_author_map{$rev_key}) {
> fatal "Found a duplicate GIT author($rev_key) in the authorsfile. Aborting dcommit!"
> }
> $rev_author_map{$rev_key}=$key
> }
972a985,997
> my $commit_entry = get_commit_entry($d);
> my $cmt_author = $commit_entry->{author};
> my $cmt_date = $commit_entry->{date};
> print "GIT AUTHOR: $cmt_author; \n";
> if(defined $cmt_author) {
> my $svn_author = $rev_author_map{$cmt_author};
> #Here we check if the git commit author matches an author in the authorsfile
> if ((not (defined $svn_author)) || $svn_author eq "") {
> fatal "The git author: $cmt_author was not found in the authors file. Make sure you have commited as a user listed in the authors file. Note:matching is case sensitive.";
> }
> print "SVN AUTHOR: $svn_author\n";
> }
>
984c1009
<
---
> my $ra = Git::SVN::Ra->new($url);
987c1012
< ra => Git::SVN::Ra->new($url),
---
> ra => $ra,
995a1021,1032
> #Here we coerce SVN into accepting the correct user according to the reverse mapping.
> if(defined $cmt_author) {
> my $svn_author = $rev_author_map{$cmt_author};
> print "SVN AUTHOR: $svn_author\n";
> $ra->change_rev_prop($cmt_rev, 'svn:author', $svn_author)
> }
> #Here we coerce SVN into accepting the commit date from Git.
> if ( defined $cmt_date ) {
> $cmt_date = strftime("%Y-%m-%dT%H:%M:%S.000000Z", gmtime($cmt_date));
> print "SVN DATE SET TO: $cmt_date\n";
> $ra->change_rev_prop($cmt_rev, 'svn:date', $cmt_date);
> }
1748c1785
< my %log_entry = ( log => '', tree => get_tree_from_treeish($treeish) );
---
> my %log_entry = ( log => '', tree => get_tree_from_treeish($treeish), author =>undef, date => undef );
1758a1796
> my $date;
1764c1802,1805
< $author = $1 if (/^author (.*>)/);
---
> if(/^author (.*>) (\d+) ([\-\+]?\d+)$/o){
> $author = $1;
> $date = $2;
> }
1782a1824,1825
> $log_entry{author} = $author || undef;
> $log_entry{date} = $date || undef;
Ответ 6
Гитуб на помощь, как обычно! Их быстрый обзор git svn переходит в пользовательское сопоставление: http://help.github.com/svn-importing/
В принципе, вы создаете файл, который содержит нужные вам сопоставления.