2011-03-16 88 views
24

我想在旧版本的Subversion版本库上使用git。我们有多个用户在使用新的git remote(origin/master),这是旧版repo的git svn克隆。问题是,当我们执行git svn dcommit将新git repo的更改推送到旧的subversion repo时,提交者的用户名会丢失,而是被git svn clone'd用户的信息所取代。有没有办法在dcommit上保存提交者的信息到颠覆者中?git svn dcommit与svn用户名

+0

因此,你只克隆SVN只有一次,并且完成了svn克隆回购的git克隆? – khmarbaise 2011-03-16 16:46:19

回答

0

要求每个人都使用“签署的off-by”或其中的每一个承诺的消息在他们的用户名的其他方式。这是一个相当丑陋的解决方案,但AFAIK是唯一可以在不破解git-svn源代码的情况下完成的。

+0

如果我正确理解该要求,则不是这样。查看我的答案以获得实际解决方案。 – 2011-05-02 19:43:55

-1

Github的救援和往常一样!他们的git svn快速概览进入用户映射:http://help.github.com/svn-importing/

基本上,你创建一个包含你想要的映射的文件。

+3

我不确定这会起作用。作者映射用于将SVN导入Git,而不是将您的Git提交回SVN。 – awendt 2011-05-04 12:56:11

+0

我相信它有效。当然,我已经使用git-svn来处理SVN仓库,而不仅仅是一个导入工具。 – 2011-05-17 14:12:04

+0

这并没有解释如何做任何事情,链接不再包含用户映射信息,即使它做到了,我不认为它适用于当您推送到svn – 2013-05-23 19:28:40

5

您可以使用git - svn的与--add-author-from--use-log-author。前者表示提交消息中的From:行中的git作者,后者进行反向转换。

这就是说,repository formats matter和颠覆库格式比git的一个穷。它不支持合并,或提交者与作者或提交时间不同于推送时间。 git-svn可以在本地获得git ui,但对于数据模型却无能为力。希望你能够迁移到一个git仓库,可能有一个svn前端(现在有git-svnserver和github的闭源选项)。

+1

它只将提交者信息保留为提交消息中的注释。它不会将更改推送为适当的提交者。 – vquintans 2014-06-19 16:20:22

+1

是的。合适的提交者只能通过外部映射来确定,因为用户名约定不同(git的电子邮件风格,与svn的验证绑定)。 – Tobu 2014-06-20 17:22:11

1

我知道这是一个很老的话题,但如果有人有兴趣,我添加这个技巧到我的本地混帐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文件,它会使用它,它会一直尝试和设置日期。此外,如果你有一个给定的git用户有多个SVN帐户,它只会选择一个。

而我才刚刚开始在愤怒中使用它,但我认为它可能做的工作,祈祷!

问候 亚当

1

我修改了一下提出的修补程序通过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 $!; 
0

这是从亚当萨顿的回答 另一略加修改它创建一个反向映射从作者文件,并做一些额外的检查重复和/或缺少作者。 它还告诉你在哪个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;