Merge branch 'maint'
authorJunio C Hamano <gitster@pobox.com>
Wed, 6 May 2009 05:52:17 +0000 (22:52 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 6 May 2009 05:52:17 +0000 (22:52 -0700)
* maint:
improve error message in config.c
t4018-diff-funcname: add cpp xfuncname pattern to syntax test
Work around BSD whose typeof(tv.tv_sec) != time_t
git-am.txt: reword extra headers in message body
git-am.txt: Use date or value instead of time or timestamp
git-am.txt: add an 'a', say what 'it' is, simplify a sentence
dir.c: Fix two minor grammatical errors in comments
git-svn: fix a sloppy Getopt::Long usage

1  2 
dir.c
git-svn.perl
diff --combined dir.c
index 15677da47c9dfc6bcb8f7f0b06bed16cf6f723ae,8b6c1f4755318375878e3cb7290441fcdf6a4eaa..6aae09a22e54a7b9291ed1b6acf79529c6029a49
--- 1/dir.c
--- 2/dir.c
+++ b/dir.c
@@@ -53,7 -53,7 +53,7 @@@ int common_prefix(const char **pathspec
  }
  
  /*
-  * Does 'match' matches the given name?
+  * Does 'match' match the given name?
   * A match is found if
   *
   * (1) the 'match' string is leading directory of 'name', or
@@@ -156,7 -156,7 +156,7 @@@ void add_exclude(const char *string, co
        if (len && string[len - 1] == '/') {
                char *s;
                x = xmalloc(sizeof(*x) + len);
 -              s = (char*)(x+1);
 +              s = (char *)(x+1);
                memcpy(s, string, len - 1);
                s[len - 1] = '\0';
                string = s;
@@@ -290,7 -290,7 +290,7 @@@ static void prep_exclude(struct dir_str
        dir->basebuf[baselen] = '\0';
  }
  
- /* Scan the list and let the last match determines the fate.
+ /* Scan the list and let the last match determine the fate.
   * Return 1 for exclude, 0 for include and -1 for undecided.
   */
  static int excluded_1(const char *pathname,
@@@ -487,14 -487,14 +487,14 @@@ static enum directory_treatment treat_d
                return recurse_into_directory;
  
        case index_gitdir:
 -              if (dir->show_other_directories)
 +              if (dir->flags & DIR_SHOW_OTHER_DIRECTORIES)
                        return ignore_directory;
                return show_directory;
  
        case index_nonexistent:
 -              if (dir->show_other_directories)
 +              if (dir->flags & DIR_SHOW_OTHER_DIRECTORIES)
                        break;
 -              if (!dir->no_gitlinks) {
 +              if (!(dir->flags & DIR_NO_GITLINKS)) {
                        unsigned char sha1[20];
                        if (resolve_gitlink_ref(dirname, "HEAD", sha1) == 0)
                                return show_directory;
        }
  
        /* This is the "show_other_directories" case */
 -      if (!dir->hide_empty_directories)
 +      if (!(dir->flags & DIR_HIDE_EMPTY_DIRECTORIES))
                return show_directory;
        if (!read_directory_recursive(dir, dirname, dirname, len, 1, simplify))
                return ignore_directory;
@@@ -601,7 -601,7 +601,7 @@@ static int read_directory_recursive(str
  
                        dtype = DTYPE(de);
                        exclude = excluded(dir, fullname, &dtype);
 -                      if (exclude && dir->collect_ignored
 +                      if (exclude && (dir->flags & DIR_COLLECT_IGNORED)
                            && in_pathspec(fullname, baselen + len, simplify))
                                dir_add_ignored(dir, fullname, baselen + len);
  
                         * Excluded? If we don't explicitly want to show
                         * ignored files, ignore it
                         */
 -                      if (exclude && !dir->show_ignored)
 +                      if (exclude && !(dir->flags & DIR_SHOW_IGNORED))
                                continue;
  
                        if (dtype == DT_UNKNOWN)
                         * even if we don't ignore them, since the
                         * directory may contain files that we do..
                         */
 -                      if (!exclude && dir->show_ignored) {
 +                      if (!exclude && (dir->flags & DIR_SHOW_IGNORED)) {
                                if (dtype != DT_DIR)
                                        continue;
                        }
                                len++;
                                switch (treat_directory(dir, fullname, baselen + len, simplify)) {
                                case show_directory:
 -                                      if (exclude != dir->show_ignored)
 +                                      if (exclude != !!(dir->flags
 +                                                      & DIR_SHOW_IGNORED))
                                                continue;
                                        break;
                                case recurse_into_directory:
@@@ -721,7 -720,7 +721,7 @@@ int read_directory(struct dir_struct *d
  {
        struct path_simplify *simplify;
  
 -      if (has_symlink_leading_path(strlen(path), path))
 +      if (has_symlink_leading_path(path, strlen(path)))
                return dir->nr;
  
        simplify = create_simplify(pathspec);
diff --combined git-svn.perl
index c5965c9aafe8d5f990e64e88cea1061f84584b58,3b524207ffef124ca62c82af33396fe87723be6c..ef1d30db3889d0d33b43b1d15cd19281291f5aea
@@@ -47,8 -47,7 +47,8 @@@ BEGIN 
        # import functions from Git into our packages, en masse
        no strict 'refs';
        foreach (qw/command command_oneline command_noisy command_output_pipe
 -                  command_input_pipe command_close_pipe/) {
 +                  command_input_pipe command_close_pipe
 +                  command_bidi_pipe command_close_bidi_pipe/) {
                for my $package ( qw(SVN::Git::Editor SVN::Git::Fetcher
                        Git::SVN::Migration Git::SVN::Log Git::SVN),
                        __PACKAGE__) {
@@@ -64,12 -63,11 +64,12 @@@ $sha1_short = qr/[a-f\d]{4,40}/
  my ($_stdin, $_help, $_edit,
        $_message, $_file,
        $_template, $_shared,
 -      $_version, $_fetch_all, $_no_rebase,
 +      $_version, $_fetch_all, $_no_rebase, $_fetch_parent,
        $_merge, $_strategy, $_dry_run, $_local,
        $_prefix, $_no_checkout, $_url, $_verbose,
        $_git_format, $_commit_url, $_tag);
  $Git::SVN::_follow_parent = 1;
 +$_q ||= 0;
  my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username,
                      'config-dir=s' => \$Git::SVN::Ra::config_dir,
                      'no-auth-cache' => \$Git::SVN::Prompt::_no_auth_cache,
@@@ -82,7 -80,7 +82,7 @@@ my %fc_opts = ( 'follow-parent|follow!
                'useSvnsyncProps' => \$Git::SVN::_use_svnsync_props,
                'log-window-size=i' => \$Git::SVN::Ra::_log_window_size,
                'no-checkout' => \$_no_checkout,
 -              'quiet|q' => \$_q,
 +              'quiet|q+' => \$_q,
                'repack-flags|repack-args|repack-opts=s' =>
                   \$Git::SVN::_repack_flags,
                'use-log-author' => \$Git::SVN::_use_log_author,
@@@ -113,7 -111,6 +113,7 @@@ my %cmd = 
        fetch => [ \&cmd_fetch, "Download new revisions from SVN",
                        { 'revision|r=s' => \$_revision,
                          'fetch-all|all' => \$_fetch_all,
 +                        'parent|p' => \$_fetch_parent,
                           %fc_opts } ],
        clone => [ \&cmd_clone, "Initialize and fetch revisions",
                        { 'revision|r=s' => \$_revision,
                   'dry-run|n' => \$_dry_run } ],
        'set-tree' => [ \&cmd_set_tree,
                        "Set an SVN repository to a git tree-ish",
-                       { 'stdin|' => \$_stdin, %cmt_opts, %fc_opts, } ],
+                       { 'stdin' => \$_stdin, %cmt_opts, %fc_opts, } ],
        'create-ignore' => [ \&cmd_create_ignore,
                             'Create a .gitignore per svn:ignore',
                             { 'revision|r=i' => \$_revision
@@@ -328,7 -325,6 +328,7 @@@ sub do_git_init_db 
                command_noisy(@init_db);
                $_repository = Git->repository(Repository => ".git");
        }
 +      command_noisy('config', 'core.autocrlf', 'false');
        my $set;
        my $pfx = "svn-remote.$Git::SVN::default_repo_id";
        foreach my $i (keys %icv) {
                command_noisy('config', "$pfx.$i", $icv{$i});
                $set = $i;
        }
 +      my $ignore_regex = \$SVN::Git::Fetcher::_ignore_regex;
 +      command_noisy('config', "$pfx.ignore-paths", $$ignore_regex)
 +              if defined $$ignore_regex;
  }
  
  sub init_subdir {
@@@ -387,21 -380,12 +387,21 @@@ sub cmd_fetch 
        }
        my ($remote) = @_;
        if (@_ > 1) {
 -              die "Usage: $0 fetch [--all] [svn-remote]\n";
 +              die "Usage: $0 fetch [--all] [--parent] [svn-remote]\n";
        }
 -      $remote ||= $Git::SVN::default_repo_id;
 -      if ($_fetch_all) {
 +      if ($_fetch_parent) {
 +              my ($url, $rev, $uuid, $gs) = working_head_info('HEAD');
 +              unless ($gs) {
 +                      die "Unable to determine upstream SVN information from ",
 +                          "working tree history\n";
 +              }
 +              # just fetch, don't checkout.
 +              $_no_checkout = 'true';
 +              $_fetch_all ? $gs->fetch_all : $gs->fetch;
 +      } elsif ($_fetch_all) {
                cmd_multi_fetch();
        } else {
 +              $remote ||= $Git::SVN::default_repo_id;
                Git::SVN::fetch_all($remote, Git::SVN::read_all_remotes());
        }
  }
@@@ -1269,40 -1253,6 +1269,40 @@@ sub cmt_metadata 
                command(qw/cat-file commit/, shift)))[-1]);
  }
  
 +sub cmt_sha2rev_batch {
 +      my %s2r;
 +      my ($pid, $in, $out, $ctx) = command_bidi_pipe(qw/cat-file --batch/);
 +      my $list = shift;
 +
 +      foreach my $sha (@{$list}) {
 +              my $first = 1;
 +              my $size = 0;
 +              print $out $sha, "\n";
 +
 +              while (my $line = <$in>) {
 +                      if ($first && $line =~ /^[[:xdigit:]]{40}\smissing$/) {
 +                              last;
 +                      } elsif ($first &&
 +                             $line =~ /^[[:xdigit:]]{40}\scommit\s(\d+)$/) {
 +                              $first = 0;
 +                              $size = $1;
 +                              next;
 +                      } elsif ($line =~ /^(git-svn-id: )/) {
 +                              my (undef, $rev, undef) =
 +                                                    extract_metadata($line);
 +                              $s2r{$sha} = $rev;
 +                      }
 +
 +                      $size -= length($line);
 +                      last if ($size == 0);
 +              }
 +      }
 +
 +      command_close_bidi_pipe($pid, $in, $out, $ctx);
 +
 +      return \%s2r;
 +}
 +
  sub working_head_info {
        my ($head, $refs) = @_;
        my @args = ('log', '--no-color', '--first-parent', '--pretty=medium');
@@@ -2381,13 -2331,13 +2381,13 @@@ sub do_git_commit 
  
        $self->{last_rev} = $log_entry->{revision};
        $self->{last_commit} = $commit;
 -      print "r$log_entry->{revision}";
 +      print "r$log_entry->{revision}" unless $::_q > 1;
        if (defined $log_entry->{svm_revision}) {
 -               print " (\@$log_entry->{svm_revision})";
 +               print " (\@$log_entry->{svm_revision})" unless $::_q > 1;
                 $self->rev_map_set($log_entry->{svm_revision}, $commit,
                                   0, $self->svm_uuid);
        }
 -      print " = $commit ($self->{ref_id})\n";
 +      print " = $commit ($self->{ref_id})\n" unless $::_q > 1;
        if (--$_gc_nr == 0) {
                $_gc_nr = $_gc_period;
                gc();
@@@ -2401,10 -2351,7 +2401,10 @@@ sub match_paths 
        if (my $path = $paths->{"/$self->{path}"}) {
                return ($path->{action} eq 'D') ? 0 : 1;
        }
 -      $self->{path_regex} ||= qr/^\/\Q$self->{path}\E\//;
 +      my $repos_root = $self->ra->{repos_root};
 +      my $extended_path = $self->{url} . '/' . $self->{path};
 +      $extended_path =~ s#^\Q$repos_root\E(/|$)##;
 +      $self->{path_regex} ||= qr/^\/\Q$extended_path\E\//;
        if (grep /$self->{path_regex}/, keys %$paths) {
                return 1;
        }
@@@ -3335,8 -3282,6 +3335,8 @@@ sub new 
                $self->{empty_symlinks} =
                                  _mark_empty_symlinks($git_svn, $switch_path);
        }
 +      $self->{ignore_regex} = eval { command_oneline('config', '--get',
 +                           "svn-remote.$git_svn->{repo_id}.ignore-paths") };
        $self->{empty} = {};
        $self->{dir_prop} = {};
        $self->{file_prop} = {};
@@@ -3401,10 -3346,8 +3401,10 @@@ sub in_dot_git 
  
  # return value: 0 -- don't ignore, 1 -- ignore
  sub is_path_ignored {
 -      my ($path) = @_;
 +      my ($self, $path) = @_;
        return 1 if in_dot_git($path);
 +      return 1 if defined($self->{ignore_regex}) &&
 +                  $path =~ m!$self->{ignore_regex}!;
        return 0 unless defined($_ignore_regex);
        return 1 if $path =~ m!$_ignore_regex!o;
        return 0;
@@@ -3435,7 -3378,7 +3435,7 @@@ sub git_path 
  
  sub delete_entry {
        my ($self, $path, $rev, $pb) = @_;
 -      return undef if is_path_ignored($path);
 +      return undef if $self->is_path_ignored($path);
  
        my $gpath = $self->git_path($path);
        return undef if ($gpath eq '');
@@@ -3468,7 -3411,7 +3468,7 @@@ sub open_file 
        my ($self, $path, $pb, $rev) = @_;
        my ($mode, $blob);
  
 -      goto out if is_path_ignored($path);
 +      goto out if $self->is_path_ignored($path);
  
        my $gpath = $self->git_path($path);
        ($mode, $blob) = (command('ls-tree', '-z', $self->{c}, "./$gpath")
@@@ -3488,7 -3431,7 +3488,7 @@@ sub add_file 
        my ($self, $path, $pb, $cp_path, $cp_rev) = @_;
        my $mode;
  
 -      if (!is_path_ignored($path)) {
 +      if (!$self->is_path_ignored($path)) {
                my ($dir, $file) = ($path =~ m#^(.*?)/?([^/]+)$#);
                delete $self->{empty}->{$dir};
                $mode = '100644';
  
  sub add_directory {
        my ($self, $path, $cp_path, $cp_rev) = @_;
 -      goto out if is_path_ignored($path);
 +      goto out if $self->is_path_ignored($path);
        my $gpath = $self->git_path($path);
        if ($gpath eq '') {
                my ($ls, $ctx) = command_output_pipe(qw/ls-tree
@@@ -3523,7 -3466,7 +3523,7 @@@ out
  
  sub change_dir_prop {
        my ($self, $db, $prop, $value) = @_;
 -      return undef if is_path_ignored($db->{path});
 +      return undef if $self->is_path_ignored($db->{path});
        $self->{dir_prop}->{$db->{path}} ||= {};
        $self->{dir_prop}->{$db->{path}}->{$prop} = $value;
        undef;
  
  sub absent_directory {
        my ($self, $path, $pb) = @_;
 -      return undef if is_path_ignored($path);
 +      return undef if $self->is_path_ignored($path);
        $self->{absent_dir}->{$pb->{path}} ||= [];
        push @{$self->{absent_dir}->{$pb->{path}}}, $path;
        undef;
  
  sub absent_file {
        my ($self, $path, $pb) = @_;
 -      return undef if is_path_ignored($path);
 +      return undef if $self->is_path_ignored($path);
        $self->{absent_file}->{$pb->{path}} ||= [];
        push @{$self->{absent_file}->{$pb->{path}}}, $path;
        undef;
  
  sub change_file_prop {
        my ($self, $fb, $prop, $value) = @_;
 -      return undef if is_path_ignored($fb->{path});
 +      return undef if $self->is_path_ignored($fb->{path});
        if ($prop eq 'svn:executable') {
                if ($fb->{mode_b} != 120000) {
                        $fb->{mode_b} = defined $value ? 100755 : 100644;
  
  sub apply_textdelta {
        my ($self, $fb, $exp) = @_;
 -      return undef if is_path_ignored($fb->{path});
 +      return undef if $self->is_path_ignored($fb->{path});
        my $fh = $::_repository->temp_acquire('svn_delta');
        # $fh gets auto-closed() by SVN::TxDelta::apply(),
        # (but $base does not,) so dup() it for reading in close_file
  
  sub close_file {
        my ($self, $fb, $exp) = @_;
 -      return undef if is_path_ignored($fb->{path});
 +      return undef if $self->is_path_ignored($fb->{path});
  
        my $hash;
        my $path = $self->git_path($fb->{path});
@@@ -5044,22 -4987,11 +5044,22 @@@ sub cmd_blame 
                                                  '--', $path);
                my ($sha1);
                my %authors;
 +              my @buffer;
 +              my %dsha; #distinct sha keys
 +
                while (my $line = <$fh>) {
 +                      push @buffer, $line;
 +                      if ($line =~ /^([[:xdigit:]]{40})\s\d+\s\d+/) {
 +                              $dsha{$1} = 1;
 +                      }
 +              }
 +
 +              my $s2r = ::cmt_sha2rev_batch([keys %dsha]);
 +
 +              foreach my $line (@buffer) {
                        if ($line =~ /^([[:xdigit:]]{40})\s\d+\s\d+/) {
 -                              $sha1 = $1;
 -                              (undef, $rev, undef) = ::cmt_metadata($1);
 -                              $rev = '0' if (!$rev);
 +                              $rev = $s2r->{$1};
 +                              $rev = '0' if (!$rev)
                        }
                        elsif ($line =~ /^author (.*)/) {
                                $authors{$rev} = $1;