Package: git-svn Version: 1:2.20.1-2+deb10u3 Severity: important Tags: patch
-- System Information: Debian Release: 10.4 APT prefers stable-updates APT policy: (500, 'stable-updates'), (500, 'stable') Architecture: amd64 (x86_64) Foreign Architectures: armhf Kernel: Linux 4.19.0-9-amd64 (SMP w/8 CPU cores) Kernel taint flags: TAINT_WARN, TAINT_CRAP Locale: LANG=en_AU, LC_CTYPE=en_AU (charmap=ISO-8859-1), LANGUAGE=en_GB:en_AU:en (charmap=ISO-8859-1) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) LSM: AppArmor: enabled Versions of packages git-svn depends on: ii git 1:2.20.1-2+deb10u3 ii libsvn-perl 1.10.4-1+deb10u1 ii libterm-readkey-perl 2.38-1 ii libyaml-perl 1.27-1 git-svn recommends no packages. Versions of packages git-svn suggests: pn git-doc <none> ii subversion 1.10.4-1+deb10u1 -- no debconf information As described in stack overflow issue in 2011 and verified in this version as still present: https://stackoverflow.com/questions/5327924/git-svn-dcommit-with-svn-usernames I find that the commit (at least for file URL subversion) just uses the default which is the last username used to submit changes to subversion. It is fairly easy to make up a simple subversion project to demonstrate the problem. mkdir proj touch proj/README.txt svn import proj file://$(pwd)/repo -m "Initial checkin" SVN_URL=file://$(pwd)/repo svn co $SVN_URL proj.svn echo "Change from fred" >> proj.svn/README.txt svn commit --username fred proj.svn/README.txt -m "Change #1 from fred" cat > authors.txt amw = Andrew Worsley <amwors...@gmail.com> fred = Fred Smith <fred.smith@acme.local> ^D # Export to git via git-svn git svn clone --authors-file=authors.txt $SVN_URL proj.git-svn # The log shows the authors file is working svn => git git -C proj.git-svn log # Add a change from user fred shows it appears as fred as # this was the last user to submit change into subversion: echo "Change #2 from fred" >> proj.git-svn/README.txt git -C proj.git-svn commit README.txt --author='Fred Smith <fred.smith@acme.local>' -m "2nd change from user fred" git -C proj.git-svn log commit 6c203a7022cd831fe505918967bda0534106cd09 (HEAD -> master) Author: Fred Smith <fred.smith@acme.local> Date: Wed Jul 29 10:52:36 2020 +1000 2nd change from user fred commit 16b1728f0fe30a9c42098ad42b8da37a7b4405da (git-svn) Author: Fred Smith <fred.smith@acme.local> Date: Wed Jul 29 00:43:58 2020 +0000 Change #1 from fred git-svn-id: file:///build/tmp/repo@2 bb13463d-1302-4b91-af5e-7ea19058a0f6 commit 2e2138b9af3bc8445f5fcba8e2e4c77e3ea78349 Author: Andrew Worsley <amwors...@gmail.com> Date: Wed Jul 29 00:40:09 2020 +0000 Initial checkin git-svn-id: file:///build/tmp/repo@1 bb13463d-1302-4b91-af5e-7ea19058a0f6 # Now try it as user amw (which is my login user) echo "Change #2 from amw" >> proj.git-svn/README.txt git -C proj.git-svn commit README.txt -m "2nd change from user amw" git -C proj.git-svn log commit 5704bbe7bc60a3a6f29ca4122706fdc648cde2e1 (HEAD -> master) Author: Andrew Worsley <amwors...@gmail.com> Date: Wed Jul 29 10:54:48 2020 +1000 2nd change from user amw commit 5398dbf30ee59d579bc7b2a60bab5f4088254cdf (git-svn) Author: Fred Smith <fred.smith@acme.local> Date: Wed Jul 29 00:53:20 2020 +0000 2nd change from user fred git-svn-id: file:///build/tmp/repo@3 bb13463d-1302-4b91-af5e-7ea19058a0f6 commit 16b1728f0fe30a9c42098ad42b8da37a7b4405da Author: Fred Smith <fred.smith@acme.local> Date: Wed Jul 29 00:43:58 2020 +0000 Change #1 from fred git-svn-id: file:///build/tmp/repo@2 bb13463d-1302-4b91-af5e-7ea19058a0f6 commit 2e2138b9af3bc8445f5fcba8e2e4c77e3ea78349 Author: Andrew Worsley <amwors...@gmail.com> Date: Wed Jul 29 00:40:09 2020 +0000 Initial checkin git-svn-id: file:///build/tmp/repo@1 bb13463d-1302-4b91-af5e-7ea19058a0f6 # Now we dcommit this 2nd amw change git -C proj.git-svn svn dcommit Committing to file:///build/tmp/repo ... M README.txt Committed r4 M README.txt r4 = bb626e195128d9582447a10d664f04323ae8c2b9 (refs/remotes/git-svn) No changes between 5704bbe7bc60a3a6f29ca4122706fdc648cde2e1 and refs/remotes/git-svn Resetting to the latest refs/remotes/git-svn # But it was commited into subversion as being from user fred ! svn log -v $SVN_URL ------------------------------------------------------------------------ r4 | fred | 2020-07-29 10:55:05 +1000 (Wed, 29 Jul 2020) | 1 line Changed paths: M /README.txt 2nd change from user amw ------------------------------------------------------------------------ r3 | fred | 2020-07-29 10:53:20 +1000 (Wed, 29 Jul 2020) | 1 line Changed paths: M /README.txt 2nd change from user fred ------------------------------------------------------------------------ r2 | fred | 2020-07-29 10:43:58 +1000 (Wed, 29 Jul 2020) | 1 line Changed paths: M /README.txt Change #1 from fred ------------------------------------------------------------------------ r1 | amw | 2020-07-29 10:40:09 +1000 (Wed, 29 Jul 2020) | 1 line Changed paths: A /README.txt Initial checkin ------------------------------------------------------------------------
--- /usr/lib/git-core/git-svn_orig 2020-04-20 10:19:12.000000000 +1000 +++ /usr/lib/git-core/git-svn 2020-07-27 16:36:55.535880152 +1000 @@ -18,6 +18,7 @@ use File::Spec; use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/; use Memoize; +use POSIX qw(strftime); use Git::SVN; use Git::SVN::Editor; @@ -978,6 +979,14 @@ if (defined($_merge_info)) { $_merge_info =~ tr{ }{\n}; } + 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 authorsfile. Aborting dcommit!"; + } + $rev_author_map{$rev_key} = $key; + } while (1) { my $d = shift @$linear_refs or last; unless (defined $last_rev) { @@ -987,10 +996,25 @@ "from commit $d~1"; } } + my $commit_entry = get_commit_entry($d); + #foreach my $k (keys %{$commit_entry}) { + # print STDERR "GIT $k entry: $commit_entry->{$k}\n"; + #} + 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}; + if ((not (defined $svn_author)) || $svn_author eq "") { + fatal "The git author: $cmt_author was not found in the authors file. ..." + } + print "SVN AUTHOR: $svn_author\n"; + } if ($_dry_run) { print "diff-tree $d~1 $d\n"; } else { my $cmt_rev; + my $ra = Git::SVN::Ra->new($url); unless (defined($_merge_info) || ! $push_merge_info) { $_merge_info = populate_merge_info($d, $gs, @@ -1001,7 +1025,7 @@ my %ed_opts = ( r => $last_rev, log => get_commit_entry($d)->{log}, - ra => Git::SVN::Ra->new($url), + ra => $ra, config => SVN::Core::config_get_config( $Git::SVN::Ra::config_dir ), @@ -1010,6 +1034,16 @@ editor_cb => sub { print "Committed r$_[0]\n"; $cmt_rev = $_[0]; + 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); + } + 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); + } }, mergeinfo => $_merge_info, svn_path => ''); @@ -1844,7 +1878,7 @@ sub get_commit_entry { my ($treeish) = shift; - my %log_entry = ( log => '', tree => get_tree_from_treeish($treeish) ); + my %log_entry = ( log => '', tree => get_tree_from_treeish($treeish), author =>undef, date => undef ); my @git_path = qw(rev-parse --git-path); my $commit_editmsg = command_oneline(@git_path, 'COMMIT_EDITMSG'); my $commit_msg = command_oneline(@git_path, 'COMMIT_MSG'); @@ -1856,12 +1890,17 @@ $type, $treeish); my $in_msg = 0; my $author; + my $date; my $saw_from = 0; my $msgbuf = ""; while (<$msg_fh>) { if (!$in_msg) { $in_msg = 1 if (/^$/); - $author = $1 if (/^author (.*>)/); + #$author = $1 if (/^author (.*>)/); + if (/^author (.*>) (\d+) ([\-\+]?\d+)$/o){ + $author = $1; + $date = $2; + } } elsif (/^git-svn-id: /) { # skip this for now, we regenerate the # correct one on re-fetch anyways @@ -1881,6 +1920,8 @@ } print $log_fh $msgbuf or croak $!; command_close_pipe($msg_fh, $ctx); + $log_entry{author} = $author || undef; + $log_entry{date} = $date || undef; } close $log_fh or croak $!;