2011-03-16 19 views
24

Estoy tratando de usar git en la parte superior de un repositorio de subversion anterior. Tenemos varios usuarios que trabajan en el nuevo control remoto de git (origen/maestro) que es un clon git svn del repositorio anterior. El problema es cuando hacemos un git svn dcommit para enviar cambios desde el nuevo repositorio de git al viejo repositorio de subversión, el nombre de usuario del commiter se pierde y en su lugar es reemplazado por la información del usuario git svn clone'd. ¿Hay alguna forma de preservar la información del committer en la subversión luego de un compromiso?git svn dcommit con nombres de usuario svn

+0

¿Has clonado el SVN solo una vez y has hecho un clon git del repositorio svn clonado? – khmarbaise

Respuesta

0

Exigir que todos utilicen un "firmado-off-by" o alguna otra forma de incluir su nombre de usuario en el mensaje de cada confirmación. Es una solución bastante fea, pero AFAIK es lo único que puedes hacer sin hackear la fuente git-svn.

+0

Eso no es verdad si entiendo el requisito correctamente. Ver mi respuesta para una solución real. –

-1

Github al rescate como de costumbre! Su visión general rápida de git svn entra en la asignación de usuarios: http://help.github.com/svn-importing/

Básicamente, usted crea un archivo que contiene las asignaciones que desea.

+3

No estoy seguro de que vaya a funcionar. El mapeo de autor es para importar SVN a Git, no para enviar sus commits de Git de nuevo a SVN. – awendt

+0

Funciona en ambos sentidos, creo. Ciertamente, he usado git-svn para trabajar con repositorios SVN, no solo como una herramienta de importación. –

+0

Esto no explica cómo hacer nada, el enlace ya no contiene la información de mapeo del usuario, y aunque lo haya hecho, no creo que funcione cuando estás presionando para svn –

5

Puede usar git-svn con --add-author-from y --use-log-author. El primero representa el autor de git en una línea From: en el mensaje de confirmación, este último realiza la transformación inversa.

Dicho esto, repository formats matter, y el formato de depósito de subversión es más pobre que el de git one. No admite fusionarse bien, o committers contra autores o tiempos de confirmación distintos de los tiempos de inserción. git-svn está bien para obtener el git ui localmente, pero no puede hacer mucho sobre el modelo de datos. Con suerte, podrá migrar a un repositorio git, posiblemente con una interfaz svn (en este momento está git-svnserver y la opción de fuente cerrada de github).

+1

Solo mantiene la información del confirmador como un comentario en el mensaje de confirmación. No empuja los cambios como el committer adecuado. – vquintans

+1

Sí. El committer adecuado solo podría determinarse a través de un mapeo externo, ya que las convenciones de usuario no son las mismas (estilo de correo electrónico para git, vinculado a la autenticación de svn). – Tobu

1

Sé que esto es un tema muy antiguo, pero si alguien está interesado que agregó este truco para mi copia local de 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; 

Esto está en contra 1.9.1-1 (versión paquete deb en Ubuntu 14.04). No es configurable, en el sentido de que si tiene un archivo users.txt lo usará y siempre intentará establecer la fecha. Además, si tienes varias cuentas SVN para un usuario determinado de git, solo seleccionará una.

Y apenas estoy comenzando a usarlo con enojo, pero creo que podría hacer el trabajo, con los dedos cruzados!

Saludos Adam

1

he modificado un poco el parche propuesto por Adam Sutton modo que git svn dcommit acepta --commit-author opción:

--- ./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

Ésta es otra versión ligeramente modificada de la respuesta de Adam Sutton Se crea una asignación inversa del archivo de los autores y realiza algunas comprobaciones adicionales de autores duplicados y/o faltantes. También le dice en la entrada qué usuario de Git se asignó a qué usuario SVN se compromete cada uno, incluso cuando se ejecuta 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; 
Cuestiones relacionadas