svn - subversion - subgit
git svn dcommit con nombres de usuario svn (6)
Estoy tratando de usar git en la parte superior de un repositorio de subversion anterior. Tenemos varios usuarios trabajando en el nuevo git remote (origin / master) que es un clon git svn del repositorio anterior. El problema es que cuando hacemos un git svn dcommit para enviar cambios desde el nuevo repositorio de git al antiguo repositorio de subversión, el nombre de usuario del usuario se pierde y, en cambio, se reemplaza por la información del usuario clonado de git svn. ¿Hay una manera de preservar la información del comitista en la subversión en un dcommit?
Esta es otra versión ligeramente modificada de la respuesta de Adam Sutton. Crea una asignación inversa del archivo de autores y realiza algunas comprobaciones adicionales para los autores duplicados y / o faltantes. También le indica en la entrada qué usuario de Git se asignó a qué usuario de SVN para cada confirmación, incluso cuando se ejecuta git svn dcommit --dry-run.
[root@qa-travel-centos 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;
Exija a todos que utilicen un "firmado" 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.
Github al rescate como de costumbre! Su resumen rápido de git svn se relaciona con la asignación de usuarios: http://help.github.com/svn-importing/
Básicamente, crea un archivo que contiene las asignaciones que desea.
Sé que este es un tema muy antiguo, pero si a alguien le interesa, agregué este truco a 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 es contra 1.9.1-1 (versión del paquete deb en Ubuntu 14.04). No es configurable, en el sentido de que si tiene un archivo users.txt, lo utilizará y siempre intentará establecer la fecha. Además, si tiene varias cuentas SVN para un usuario de git determinado, solo elegirá una.
Y apenas estoy empezando a usarlo enojado, pero creo que podría funcionar, ¡con los dedos cruzados!
Saludos Adam
git svn dcommit
un poco el parche propuesto por para que git svn dcommit
acepte la opción --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 $!;
Puede usar git-svn con --add-author-from
y --use-log-author
. El primero representa al autor de git en una línea From:
en el mensaje de confirmación, el segundo realiza la transformación inversa.
Dicho esto, los formatos de repositorio son importantes , y el formato de repositorio de subversión es más pobre que el de git. No es compatible con la fusión bien, ni con los comisarios contra los autores ni los 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 con el modelo de datos. Esperamos que pueda migrar a un repositorio git, posiblemente con una interfaz svn (en este momento hay git-svnserver y la opción de código cerrado de github).