mirror of
https://github.com/git/git.git
synced 2024-11-01 06:47:52 +01:00
Merge branch 'master' of git://bogomips.org/git-svn
* 'master' of git://bogomips.org/git-svn: git-svn.perl: fix a false-positive in the "already exists" test git-svn.perl: perform deletions before anything else git-svn: Fix time zone in --localtime git-svn: un-break "git svn rebase" when log.abbrevCommit=true git-svn: remove redundant porcelain option to rev-list completion: add --interactive option to git svn dcommit
This commit is contained in:
commit
675fff45a7
3 changed files with 59 additions and 44 deletions
|
@ -2512,7 +2512,7 @@ _git_svn ()
|
||||||
__gitcomp "
|
__gitcomp "
|
||||||
--merge --strategy= --verbose --dry-run
|
--merge --strategy= --verbose --dry-run
|
||||||
--fetch-all --no-rebase --commit-url
|
--fetch-all --no-rebase --commit-url
|
||||||
--revision $cmt_opts $fc_opts
|
--revision --interactive $cmt_opts $fc_opts
|
||||||
"
|
"
|
||||||
;;
|
;;
|
||||||
set-tree,--*)
|
set-tree,--*)
|
||||||
|
|
68
git-svn.perl
68
git-svn.perl
|
@ -1878,8 +1878,7 @@ sub cmt_sha2rev_batch {
|
||||||
|
|
||||||
sub working_head_info {
|
sub working_head_info {
|
||||||
my ($head, $refs) = @_;
|
my ($head, $refs) = @_;
|
||||||
my @args = qw/log --no-color --no-decorate --first-parent
|
my @args = qw/rev-list --first-parent --pretty=medium/;
|
||||||
--pretty=medium/;
|
|
||||||
my ($fh, $ctx) = command_output_pipe(@args, $head);
|
my ($fh, $ctx) = command_output_pipe(@args, $head);
|
||||||
my $hash;
|
my $hash;
|
||||||
my %max;
|
my %max;
|
||||||
|
@ -2029,6 +2028,7 @@ package Git::SVN;
|
||||||
use File::Path qw/mkpath/;
|
use File::Path qw/mkpath/;
|
||||||
use File::Copy qw/copy/;
|
use File::Copy qw/copy/;
|
||||||
use IPC::Open3;
|
use IPC::Open3;
|
||||||
|
use Time::Local;
|
||||||
use Memoize; # core since 5.8.0, Jul 2002
|
use Memoize; # core since 5.8.0, Jul 2002
|
||||||
use Memoize::Storable;
|
use Memoize::Storable;
|
||||||
|
|
||||||
|
@ -3287,6 +3287,14 @@ sub get_untracked {
|
||||||
\@out;
|
\@out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub get_tz {
|
||||||
|
# some systmes don't handle or mishandle %z, so be creative.
|
||||||
|
my $t = shift || time;
|
||||||
|
my $gm = timelocal(gmtime($t));
|
||||||
|
my $sign = qw( + + - )[ $t <=> $gm ];
|
||||||
|
return sprintf("%s%02d%02d", $sign, (gmtime(abs($t - $gm)))[2,1]);
|
||||||
|
}
|
||||||
|
|
||||||
# parse_svn_date(DATE)
|
# parse_svn_date(DATE)
|
||||||
# --------------------
|
# --------------------
|
||||||
# Given a date (in UTC) from Subversion, return a string in the format
|
# Given a date (in UTC) from Subversion, return a string in the format
|
||||||
|
@ -3319,8 +3327,7 @@ sub parse_svn_date {
|
||||||
delete $ENV{TZ};
|
delete $ENV{TZ};
|
||||||
}
|
}
|
||||||
|
|
||||||
my $our_TZ =
|
my $our_TZ = get_tz();
|
||||||
POSIX::strftime('%Z', $S, $M, $H, $d, $m - 1, $Y - 1900);
|
|
||||||
|
|
||||||
# This converts $epoch_in_UTC into our local timezone.
|
# This converts $epoch_in_UTC into our local timezone.
|
||||||
my ($sec, $min, $hour, $mday, $mon, $year,
|
my ($sec, $min, $hour, $mday, $mon, $year,
|
||||||
|
@ -3920,7 +3927,7 @@ sub rebuild {
|
||||||
my ($base_rev, $head) = ($partial ? $self->rev_map_max_norebuild(1) :
|
my ($base_rev, $head) = ($partial ? $self->rev_map_max_norebuild(1) :
|
||||||
(undef, undef));
|
(undef, undef));
|
||||||
my ($log, $ctx) =
|
my ($log, $ctx) =
|
||||||
command_output_pipe(qw/rev-list --pretty=raw --no-color --reverse/,
|
command_output_pipe(qw/rev-list --pretty=raw --reverse/,
|
||||||
($head ? "$head.." : "") . $self->refname,
|
($head ? "$head.." : "") . $self->refname,
|
||||||
'--');
|
'--');
|
||||||
my $metadata_url = $self->metadata_url;
|
my $metadata_url = $self->metadata_url;
|
||||||
|
@ -5130,7 +5137,7 @@ sub rmdirs {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub open_or_add_dir {
|
sub open_or_add_dir {
|
||||||
my ($self, $full_path, $baton) = @_;
|
my ($self, $full_path, $baton, $deletions) = @_;
|
||||||
my $t = $self->{types}->{$full_path};
|
my $t = $self->{types}->{$full_path};
|
||||||
if (!defined $t) {
|
if (!defined $t) {
|
||||||
die "$full_path not known in r$self->{r} or we have a bug!\n";
|
die "$full_path not known in r$self->{r} or we have a bug!\n";
|
||||||
|
@ -5139,7 +5146,7 @@ sub open_or_add_dir {
|
||||||
no warnings 'once';
|
no warnings 'once';
|
||||||
# SVN::Node::none and SVN::Node::file are used only once,
|
# SVN::Node::none and SVN::Node::file are used only once,
|
||||||
# so we're shutting up Perl's warnings about them.
|
# so we're shutting up Perl's warnings about them.
|
||||||
if ($t == $SVN::Node::none) {
|
if ($t == $SVN::Node::none || defined($deletions->{$full_path})) {
|
||||||
return $self->add_directory($full_path, $baton,
|
return $self->add_directory($full_path, $baton,
|
||||||
undef, -1, $self->{pool});
|
undef, -1, $self->{pool});
|
||||||
} elsif ($t == $SVN::Node::dir) {
|
} elsif ($t == $SVN::Node::dir) {
|
||||||
|
@ -5154,17 +5161,18 @@ sub open_or_add_dir {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub ensure_path {
|
sub ensure_path {
|
||||||
my ($self, $path) = @_;
|
my ($self, $path, $deletions) = @_;
|
||||||
my $bat = $self->{bat};
|
my $bat = $self->{bat};
|
||||||
my $repo_path = $self->repo_path($path);
|
my $repo_path = $self->repo_path($path);
|
||||||
return $bat->{''} unless (length $repo_path);
|
return $bat->{''} unless (length $repo_path);
|
||||||
|
|
||||||
my @p = split m#/+#, $repo_path;
|
my @p = split m#/+#, $repo_path;
|
||||||
my $c = shift @p;
|
my $c = shift @p;
|
||||||
$bat->{$c} ||= $self->open_or_add_dir($c, $bat->{''});
|
$bat->{$c} ||= $self->open_or_add_dir($c, $bat->{''}, $deletions);
|
||||||
while (@p) {
|
while (@p) {
|
||||||
my $c0 = $c;
|
my $c0 = $c;
|
||||||
$c .= '/' . shift @p;
|
$c .= '/' . shift @p;
|
||||||
$bat->{$c} ||= $self->open_or_add_dir($c, $bat->{$c0});
|
$bat->{$c} ||= $self->open_or_add_dir($c, $bat->{$c0}, $deletions);
|
||||||
}
|
}
|
||||||
return $bat->{$c};
|
return $bat->{$c};
|
||||||
}
|
}
|
||||||
|
@ -5221,9 +5229,9 @@ sub apply_autoprops {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub A {
|
sub A {
|
||||||
my ($self, $m) = @_;
|
my ($self, $m, $deletions) = @_;
|
||||||
my ($dir, $file) = split_path($m->{file_b});
|
my ($dir, $file) = split_path($m->{file_b});
|
||||||
my $pbat = $self->ensure_path($dir);
|
my $pbat = $self->ensure_path($dir, $deletions);
|
||||||
my $fbat = $self->add_file($self->repo_path($m->{file_b}), $pbat,
|
my $fbat = $self->add_file($self->repo_path($m->{file_b}), $pbat,
|
||||||
undef, -1);
|
undef, -1);
|
||||||
print "\tA\t$m->{file_b}\n" unless $::_q;
|
print "\tA\t$m->{file_b}\n" unless $::_q;
|
||||||
|
@ -5233,9 +5241,9 @@ sub A {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub C {
|
sub C {
|
||||||
my ($self, $m) = @_;
|
my ($self, $m, $deletions) = @_;
|
||||||
my ($dir, $file) = split_path($m->{file_b});
|
my ($dir, $file) = split_path($m->{file_b});
|
||||||
my $pbat = $self->ensure_path($dir);
|
my $pbat = $self->ensure_path($dir, $deletions);
|
||||||
my $fbat = $self->add_file($self->repo_path($m->{file_b}), $pbat,
|
my $fbat = $self->add_file($self->repo_path($m->{file_b}), $pbat,
|
||||||
$self->url_path($m->{file_a}), $self->{r});
|
$self->url_path($m->{file_a}), $self->{r});
|
||||||
print "\tC\t$m->{file_a} => $m->{file_b}\n" unless $::_q;
|
print "\tC\t$m->{file_a} => $m->{file_b}\n" unless $::_q;
|
||||||
|
@ -5252,9 +5260,9 @@ sub delete_entry {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub R {
|
sub R {
|
||||||
my ($self, $m) = @_;
|
my ($self, $m, $deletions) = @_;
|
||||||
my ($dir, $file) = split_path($m->{file_b});
|
my ($dir, $file) = split_path($m->{file_b});
|
||||||
my $pbat = $self->ensure_path($dir);
|
my $pbat = $self->ensure_path($dir, $deletions);
|
||||||
my $fbat = $self->add_file($self->repo_path($m->{file_b}), $pbat,
|
my $fbat = $self->add_file($self->repo_path($m->{file_b}), $pbat,
|
||||||
$self->url_path($m->{file_a}), $self->{r});
|
$self->url_path($m->{file_a}), $self->{r});
|
||||||
print "\tR\t$m->{file_a} => $m->{file_b}\n" unless $::_q;
|
print "\tR\t$m->{file_a} => $m->{file_b}\n" unless $::_q;
|
||||||
|
@ -5263,14 +5271,14 @@ sub R {
|
||||||
$self->close_file($fbat,undef,$self->{pool});
|
$self->close_file($fbat,undef,$self->{pool});
|
||||||
|
|
||||||
($dir, $file) = split_path($m->{file_a});
|
($dir, $file) = split_path($m->{file_a});
|
||||||
$pbat = $self->ensure_path($dir);
|
$pbat = $self->ensure_path($dir, $deletions);
|
||||||
$self->delete_entry($m->{file_a}, $pbat);
|
$self->delete_entry($m->{file_a}, $pbat);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub M {
|
sub M {
|
||||||
my ($self, $m) = @_;
|
my ($self, $m, $deletions) = @_;
|
||||||
my ($dir, $file) = split_path($m->{file_b});
|
my ($dir, $file) = split_path($m->{file_b});
|
||||||
my $pbat = $self->ensure_path($dir);
|
my $pbat = $self->ensure_path($dir, $deletions);
|
||||||
my $fbat = $self->open_file($self->repo_path($m->{file_b}),
|
my $fbat = $self->open_file($self->repo_path($m->{file_b}),
|
||||||
$pbat,$self->{r},$self->{pool});
|
$pbat,$self->{r},$self->{pool});
|
||||||
print "\t$m->{chg}\t$m->{file_b}\n" unless $::_q;
|
print "\t$m->{chg}\t$m->{file_b}\n" unless $::_q;
|
||||||
|
@ -5340,9 +5348,9 @@ sub chg_file {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub D {
|
sub D {
|
||||||
my ($self, $m) = @_;
|
my ($self, $m, $deletions) = @_;
|
||||||
my ($dir, $file) = split_path($m->{file_b});
|
my ($dir, $file) = split_path($m->{file_b});
|
||||||
my $pbat = $self->ensure_path($dir);
|
my $pbat = $self->ensure_path($dir, $deletions);
|
||||||
print "\tD\t$m->{file_b}\n" unless $::_q;
|
print "\tD\t$m->{file_b}\n" unless $::_q;
|
||||||
$self->delete_entry($m->{file_b}, $pbat);
|
$self->delete_entry($m->{file_b}, $pbat);
|
||||||
}
|
}
|
||||||
|
@ -5374,11 +5382,19 @@ sub DESTROY {
|
||||||
sub apply_diff {
|
sub apply_diff {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
my $mods = $self->{mods};
|
my $mods = $self->{mods};
|
||||||
my %o = ( D => 1, R => 0, C => -1, A => 3, M => 3, T => 3 );
|
my %o = ( D => 0, C => 1, R => 2, A => 3, M => 4, T => 5 );
|
||||||
|
my %deletions;
|
||||||
|
|
||||||
|
foreach my $m (@$mods) {
|
||||||
|
if ($m->{chg} eq "D") {
|
||||||
|
$deletions{$m->{file_b}} = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach my $m (sort { $o{$a->{chg}} <=> $o{$b->{chg}} } @$mods) {
|
foreach my $m (sort { $o{$a->{chg}} <=> $o{$b->{chg}} } @$mods) {
|
||||||
my $f = $m->{chg};
|
my $f = $m->{chg};
|
||||||
if (defined $o{$f}) {
|
if (defined $o{$f}) {
|
||||||
$self->$f($m);
|
$self->$f($m, \%deletions);
|
||||||
} else {
|
} else {
|
||||||
fatal("Invalid change type: $f");
|
fatal("Invalid change type: $f");
|
||||||
}
|
}
|
||||||
|
@ -5994,7 +6010,6 @@ package Git::SVN::Log;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use POSIX qw/strftime/;
|
use POSIX qw/strftime/;
|
||||||
use Time::Local;
|
|
||||||
use constant commit_log_separator => ('-' x 72) . "\n";
|
use constant commit_log_separator => ('-' x 72) . "\n";
|
||||||
use vars qw/$TZ $limit $color $pager $non_recursive $verbose $oneline
|
use vars qw/$TZ $limit $color $pager $non_recursive $verbose $oneline
|
||||||
%rusers $show_commit $incremental/;
|
%rusers $show_commit $incremental/;
|
||||||
|
@ -6104,11 +6119,8 @@ sub run_pager {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub format_svn_date {
|
sub format_svn_date {
|
||||||
# some systmes don't handle or mishandle %z, so be creative.
|
|
||||||
my $t = shift || time;
|
my $t = shift || time;
|
||||||
my $gm = timelocal(gmtime($t));
|
my $gmoff = Git::SVN::get_tz($t);
|
||||||
my $sign = qw( + + - )[ $t <=> $gm ];
|
|
||||||
my $gmoff = sprintf("%s%02d%02d", $sign, (gmtime(abs($t - $gm)))[2,1]);
|
|
||||||
return strftime("%Y-%m-%d %H:%M:%S $gmoff (%a, %d %b %Y)", localtime($t));
|
return strftime("%Y-%m-%d %H:%M:%S $gmoff (%a, %d %b %Y)", localtime($t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,9 +92,11 @@ test_expect_success "$name" '
|
||||||
echo yyy > bar/zzz/yyy &&
|
echo yyy > bar/zzz/yyy &&
|
||||||
git update-index --add bar/zzz/yyy &&
|
git update-index --add bar/zzz/yyy &&
|
||||||
git commit -m "$name" &&
|
git commit -m "$name" &&
|
||||||
test_must_fail git svn set-tree --find-copies-harder --rmdir \
|
git svn set-tree --find-copies-harder --rmdir \
|
||||||
${remotes_git_svn}..mybranch3' || true
|
${remotes_git_svn}..mybranch3 &&
|
||||||
|
svn_cmd up "$SVN_TREE" &&
|
||||||
|
test -d "$SVN_TREE"/bar/zzz &&
|
||||||
|
test -e "$SVN_TREE"/bar/zzz/yyy ' || true
|
||||||
|
|
||||||
name='detect node change from directory to file #2'
|
name='detect node change from directory to file #2'
|
||||||
test_expect_success "$name" '
|
test_expect_success "$name" '
|
||||||
|
@ -134,10 +136,10 @@ test_expect_success "$name" '
|
||||||
test -x "$SVN_TREE"/exec.sh'
|
test -x "$SVN_TREE"/exec.sh'
|
||||||
|
|
||||||
|
|
||||||
name='executable file becomes a symlink to bar/zzz (file)'
|
name='executable file becomes a symlink to file'
|
||||||
test_expect_success "$name" '
|
test_expect_success "$name" '
|
||||||
rm exec.sh &&
|
rm exec.sh &&
|
||||||
ln -s bar/zzz exec.sh &&
|
ln -s file exec.sh &&
|
||||||
git update-index exec.sh &&
|
git update-index exec.sh &&
|
||||||
git commit -m "$name" &&
|
git commit -m "$name" &&
|
||||||
git svn set-tree --find-copies-harder --rmdir \
|
git svn set-tree --find-copies-harder --rmdir \
|
||||||
|
@ -148,14 +150,14 @@ test_expect_success "$name" '
|
||||||
name='new symlink is added to a file that was also just made executable'
|
name='new symlink is added to a file that was also just made executable'
|
||||||
|
|
||||||
test_expect_success "$name" '
|
test_expect_success "$name" '
|
||||||
chmod +x bar/zzz &&
|
chmod +x file &&
|
||||||
ln -s bar/zzz exec-2.sh &&
|
ln -s file exec-2.sh &&
|
||||||
git update-index --add bar/zzz exec-2.sh &&
|
git update-index --add file exec-2.sh &&
|
||||||
git commit -m "$name" &&
|
git commit -m "$name" &&
|
||||||
git svn set-tree --find-copies-harder --rmdir \
|
git svn set-tree --find-copies-harder --rmdir \
|
||||||
${remotes_git_svn}..mybranch5 &&
|
${remotes_git_svn}..mybranch5 &&
|
||||||
svn_cmd up "$SVN_TREE" &&
|
svn_cmd up "$SVN_TREE" &&
|
||||||
test -x "$SVN_TREE"/bar/zzz &&
|
test -x "$SVN_TREE"/file &&
|
||||||
test -h "$SVN_TREE"/exec-2.sh'
|
test -h "$SVN_TREE"/exec-2.sh'
|
||||||
|
|
||||||
name='modify a symlink to become a file'
|
name='modify a symlink to become a file'
|
||||||
|
@ -195,14 +197,15 @@ name='check imported tree checksums expected tree checksums'
|
||||||
rm -f expected
|
rm -f expected
|
||||||
if test_have_prereq UTF8
|
if test_have_prereq UTF8
|
||||||
then
|
then
|
||||||
echo tree bf522353586b1b883488f2bc73dab0d9f774b9a9 > expected
|
echo tree dc68b14b733e4ec85b04ab6f712340edc5dc936e > expected
|
||||||
fi
|
fi
|
||||||
cat >> expected <<\EOF
|
cat >> expected <<\EOF
|
||||||
tree 83654bb36f019ae4fe77a0171f81075972087624
|
tree c3322890dcf74901f32d216f05c5044f670ce632
|
||||||
tree 031b8d557afc6fea52894eaebb45bec52f1ba6d1
|
tree d3ccd5035feafd17b030c5732e7808cc49122853
|
||||||
tree 0b094cbff17168f24c302e297f55bfac65eb8bd3
|
tree d03e1630363d4881e68929d532746b20b0986b83
|
||||||
tree d667270a1f7b109f5eb3aaea21ede14b56bfdd6e
|
tree 149d63cd5878155c846e8c55d7d8487de283f89e
|
||||||
tree 56a30b966619b863674f5978696f4a3594f2fca9
|
tree 312b76e4f64ce14893aeac8591eb3960b065e247
|
||||||
|
tree 149d63cd5878155c846e8c55d7d8487de283f89e
|
||||||
tree d667270a1f7b109f5eb3aaea21ede14b56bfdd6e
|
tree d667270a1f7b109f5eb3aaea21ede14b56bfdd6e
|
||||||
tree 8f51f74cf0163afc9ad68a4b1537288c4558b5a4
|
tree 8f51f74cf0163afc9ad68a4b1537288c4558b5a4
|
||||||
EOF
|
EOF
|
||||||
|
|
Loading…
Reference in a new issue