git-svn: Fix fetch --no-ignore-externals with GIT_SVN_NO_LIB=1
[gitweb.git] / git-svn.perl
index 0d58bb9b37944728baa7d8af17d714f6ee8b4509..f5c7d46341016a5ca77a52ad16fbcd8c3830678f 100755 (executable)
@@ -51,7 +51,8 @@
        $_message, $_file, $_follow_parent, $_no_metadata,
        $_template, $_shared, $_no_default_regex, $_no_graft_copy,
        $_limit, $_verbose, $_incremental, $_oneline, $_l_fmt, $_show_commit,
-       $_version, $_upgrade, $_authors, $_branch_all_refs, @_opt_m);
+       $_version, $_upgrade, $_authors, $_branch_all_refs, @_opt_m,
+       $_merge, $_strategy, $_dry_run, $_ignore_nodate);
 my (@_branch_from, %tree_map, %users, %rusers, %equiv);
 my ($_svn_co_url_revs, $_svn_pg_peg_revs);
 my @repo_path_split_cache;
@@ -64,6 +65,7 @@
                'repack:i' => \$_repack,
                'no-metadata' => \$_no_metadata,
                'quiet|q' => \$_q,
+               'ignore-nodate' => \$_ignore_nodate,
                'repack-flags|repack-args|repack-opts=s' => \$_repack_flags);
 
 my ($_trunk, $_tags, $_branches);
                        { 'message|m=s' => \$_message,
                          'file|F=s' => \$_file,
                        %cmt_opts } ],
+       dcommit => [ \&dcommit, 'Commit several diffs to merge with upstream',
+                       { 'merge|m|M' => \$_merge,
+                         'strategy|s=s' => \$_strategy,
+                         'dry-run|n' => \$_dry_run,
+                       %cmt_opts } ],
 );
 
 my $cmd;
@@ -500,6 +507,8 @@ sub commit_lib {
        my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef, 0) : ();
        my $commit_msg = "$GIT_SVN_DIR/.svn-commit.tmp.$$";
 
+       my $repo;
+       ($repo, $SVN_PATH) = repo_path_split($SVN_URL);
        set_svn_commit_env();
        foreach my $c (@revs) {
                my $log_msg = get_commit_message($c, $commit_msg);
@@ -508,6 +517,8 @@ sub commit_lib {
                # can't track down... (it's probably in the SVN code)
                defined(my $pid = open my $fh, '-|') or croak $!;
                if (!$pid) {
+                       $SVN_LOG = libsvn_connect($repo);
+                       $SVN = libsvn_connect($repo);
                        my $ed = SVN::Git::Editor->new(
                                        {       r => $r_last,
                                                ra => $SVN,
@@ -557,6 +568,33 @@ sub commit_lib {
        unlink $commit_msg;
 }
 
+sub dcommit {
+       my $gs = "refs/remotes/$GIT_SVN";
+       chomp(my @refs = safe_qx(qw/git-rev-list --no-merges/, "$gs..HEAD"));
+       foreach my $d (reverse @refs) {
+               if ($_dry_run) {
+                       print "diff-tree $d~1 $d\n";
+               } else {
+                       commit_diff("$d~1", $d);
+               }
+       }
+       return if $_dry_run;
+       fetch();
+       my @diff = safe_qx(qw/git-diff-tree HEAD/, $gs);
+       my @finish;
+       if (@diff) {
+               @finish = qw/rebase/;
+               push @finish, qw/--merge/ if $_merge;
+               push @finish, "--strategy=$_strategy" if $_strategy;
+               print STDERR "W: HEAD and $gs differ, using @finish:\n", @diff;
+       } else {
+               print "No changes between current HEAD and $gs\n",
+                     "Hard resetting to the latest $gs\n";
+               @finish = qw/reset --hard/;
+       }
+       sys('git', @finish, $gs);
+}
+
 sub show_ignore {
        $SVN_URL ||= file_to_s("$GIT_SVN_DIR/info/url");
        $_use_lib ? show_ignore_lib() : show_ignore_cmd();
@@ -782,6 +820,7 @@ sub commit_diff {
        } else {
                $ed->close_edit;
        }
+       $_message = $_file = undef;
 }
 
 ########################### utility functions #########################
@@ -1208,6 +1247,7 @@ sub assert_svn_wc_clean {
        }
        my @status = grep(!/^Performing status on external/,(`svn status`));
        @status = grep(!/^\s*$/,@status);
+       @status = grep(!/^X/,@status) if $_no_ignore_ext;
        if (scalar @status) {
                print STDERR "Tree ($SVN_WC) is not clean:\n";
                print STDERR $_ foreach @status;
@@ -1696,6 +1736,8 @@ sub next_log_entry {
                        my $rev = $1;
                        my ($author, $date, $lines) = split(/\s*\|\s*/, $_, 3);
                        ($lines) = ($lines =~ /(\d+)/);
+                       $date = '1970-01-01 00:00:00 +0000'
+                               if ($_ignore_nodate && $date eq '(no date)');
                        my ($Y,$m,$d,$H,$M,$S,$tz) = ($date =~
                                        /(\d{4})\-(\d\d)\-(\d\d)\s
                                         (\d\d)\:(\d\d)\:(\d\d)\s([\-\+]\d+)/x)
@@ -2130,7 +2172,7 @@ sub load_authors {
        open my $authors, '<', $_authors or die "Can't open $_authors $!\n";
        while (<$authors>) {
                chomp;
-               next unless /^(\S+?)\s*=\s*(.+?)\s*<(.+)>\s*$/;
+               next unless /^(\S+?|\(no author\))\s*=\s*(.+?)\s*<(.+)>\s*$/;
                my ($user, $name, $email) = ($1, $2, $3);
                $users{$user} = [$name, $email];
        }