⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 svn_load_dirs.pl.in

📁 linux subdivision ying gai ke yi le ba
💻 IN
📖 第 1 页 / 共 5 页
字号:

                      # Check that the file or directory to be renamed
                      # has the same file type.
                      if ($got_line)
                        {
                          $add_filename = $add_files[$add_index];
                          $del_filename = $del_files[$del_index];
                          if ($add_files{$add_filename}{type} ne
                              $del_files{$del_filename}{type})
                            {
                              print "File types for $del_filename and ",
                                    "$add_filename differ.\n";
                              $got_line = undef;
                            }
                        }
                    }
                } until ($got_line);

                if ($line !~ /^F$/i)
                  {
                    print "Renaming $del_filename to $add_filename.\n";

                    $repeat_loop = 1;

                    # Because subversion cannot rename the same file
                    # or directory twice, which includes doing a
                    # rename of a file in a directory that was
                    # previously renamed, a commit has to be
                    # performed.  Check if the file or directory being
                    # renamed now would cause such a problem and
                    # commit if so.
                    my $do_commit_now = 0;
                    foreach my $rename_to_filename (keys %rename_to_files)
                      {
                        if (contained_in($del_filename,
                                         $rename_to_filename,
                                         $rename_to_files{$rename_to_filename}{type}))
                          {
                            $do_commit_now = 1;
                            last;
                          }
                      }

                    if ($do_commit_now)
                      {
                        print "Now committing previously run renames.\n";
                        &commit_renames($load_dir,
                                        \@renamed_filenames,
                                        \%rename_from_files,
                                        \%rename_to_files);
                      }

                    push(@renamed_filenames, $del_filename, $add_filename);
                    {
                      my $d = $del_files{$del_filename};
                      $rename_from_files{$del_filename} = $d;
                      $rename_to_files{$add_filename}   = $d;
                    }

                    # Check that any required directories to do the
                    # rename exist.
                    my @add_segments = split('/', $add_filename);
                    pop(@add_segments);
                    my $add_dir = '';
                    my @add_dirs;
                    foreach my $segment (@add_segments)
                      {
                        $add_dir = length($add_dir) ? "$add_dir/$segment" :
                                                      $segment;
                        unless (-d $add_dir)
                          {
                            push(@add_dirs, $add_dir);
                          }
                      }

                    if (@add_dirs)
                      {
                        read_from_process($svn, 'mkdir', @add_dirs);
                      }

                    read_from_process($svn, 'mv',
                                      $del_filename, $add_filename);
                  }
              }
          } while ($repeat_loop);
      }

    # If there are any renames that have not been committed, then do
    # that now.
    if (@renamed_filenames)
      {
        &commit_renames($load_dir,
                        \@renamed_filenames,
                        \%rename_from_files,
                        \%rename_to_files);
      }

    # At this point all renames have been performed.  Now get the
    # final list of files and directories in the working copy
    # directory.  The %add_files hash will contain the list of files
    # and directories to add to the working copy and %del_files starts
    # with all the files already in the working copy and gets files
    # removed that are in the imported directory, which results in a
    # list of files that should be deleted.  %upd_files holds the list
    # of files that have been updated.
    my %add_files;
    my %del_files = &recursive_ls_and_hash($wc_import_dir_cwd);
    my %upd_files;

    # This anonymous subroutine copies files from the source directory
    # to the working copy directory.
    my $wanted = sub
      {
        s#^\./##;
        return if $_ eq '.';

        my $source_path = $_;
        my $dest_path   = "$wc_import_dir_cwd/$_";

        my ($source_type, $source_is_exe) = &file_info($source_path);
        my ($dest_type)                   = &file_info($dest_path);

        return if ($source_type ne 'd' and $source_type ne 'f');

        # Fail if the destination type exists but is of a different
        # type of file than the source type.
        if ($dest_type ne '0' and $source_type ne $dest_type)
          {
            die "$0: does not handle changing source and destination type ",
                "for '$source_path'.\n";
          }

        # Determine if the file is being added or is an update to an
        # already existing file using the file's digest.
        my $del_info = delete $del_files{$source_path};
        if (defined $del_info)
          {
            if (defined (my $del_digest = $del_info->{digest}))
              {
                my $new_digest = &digest_hash_file($source_path);
                if ($new_digest ne $del_digest)
                  {
                    print "U   $source_path\n";
                    $upd_files{$source_path} = $del_info;
                  }
              }
          }
        else
          {
            print "A   $source_path\n";
            $add_files{$source_path}{type} = $source_type;

            # Create an array reference to hold the list of properties
            # to apply to this object.
            unless (defined $add_files{$source_path}{properties})
              {
                $add_files{$source_path}{properties} = [];
              }

            # Go through the list of properties for a match on this
            # file or directory and if there is a match, then apply
            # the property to it.
            foreach my $property (@property_settings)
              {
                my $re = $property->{re};
                if ($source_path =~ $re)
                  {
                    my $property_name  = $property->{name};
                    my $property_value = $property->{value};

                    # The property value may not be set in the
                    # configuration file, since the user may just want
                    # to set the control flag.
                    if (defined $property_name and defined $property_value)
                      {
                        # Ignore properties that do not apply to
                        # directories.
                        if ($source_type eq 'd')
                          {
                            if ($property_name eq 'svn:eol-style' or
                                $property_name eq 'svn:executable' or
                                $property_name eq 'svn:keywords' or
                                $property_name eq 'svn:mime-type')
                              {
                                next;
                              }
                          }

                        # Ignore properties that do not apply to
                        # files.
                        if ($source_type eq 'f')
                          {
                            if ($property_name eq 'svn:externals' or
                                $property_name eq 'svn:ignore')
                              {
                                next;
                              }
                          }

                        print "Adding to '$source_path' property ",
                              "'$property_name' with value ",
                              "'$property_value'.\n";

                        push(@{$add_files{$source_path}{properties}},
                             $property);
                      }

                    last if $property->{control} eq 'break';
                  }
              }
          }

        # Add svn:executable to files that have their executable bit
        # set.
        if ($source_is_exe)
          {
            print "Adding to '$source_path' property 'svn:executable' with ",
                  "value ''.\n";
            my $property = {name => 'svn:executable', value => ''};
            push (@{$add_files{$source_path}{properties}},
                  $property);
          }

        # Now make sure the file or directory in the source directory
        # exists in the repository.
        if ($source_type eq 'd')
          {
            if ($dest_type eq '0')
              {
                mkdir($dest_path)
                  or die "$0: cannot mkdir '$dest_path': $!\n";
              }
          }
        elsif
          ($source_type eq 'f') {
            # Only copy the file if the digests do not match.
            if ($add_files{$source_path} or $upd_files{$source_path})
              {
                copy($source_path, $dest_path)
                  or die "$0: copy '$source_path' to '$dest_path': $!\n";
              }
          }
        else
          {
            die "$0: does not handle copying files of type '$source_type'.\n";
          }
      };

    # Now change into the directory containing the files to load.
    # First change to the original directory where this script was run
    # so that if the specified directory is a relative directory path,
    # then the script can change into it.
    chdir($orig_cwd)
      or die "$0: cannot chdir '$orig_cwd': $!\n";
    chdir($load_dir)
      or die "$0: cannot chdir '$load_dir': $!\n";

    find({no_chdir   => 1,
          preprocess => sub { sort { $b cmp $a } @_ },
          wanted     => $wanted
         }, '.');

    # The files and directories that are in %del_files are the files
    # and directories that need to be deleted.  Because svn will
    # return an error if a file or directory is deleted in a directory
    # that subsequently is deleted, first find all directories and
    # remove from the list any files and directories inside those
    # directories from this list.  Work through the list repeatedly
    # working from short to long names so that directories containing
    # other files and directories will be deleted first.
    my $repeat_loop;
    do
      {
        $repeat_loop = 0;
        my @del_files = sort {length($a) <=> length($b) || $a cmp $b}
                        keys %del_files;
        &filter_renamed_files(\@del_files, \%rename_from_files);
        foreach my $file (@del_files)
          {
            if ($del_files{$file}{type} eq 'd')
              {
                my $dir        = "$file/";
                my $dir_length = length($dir);
                foreach my $f (@del_files)
                  {
                    next if $file eq $f;
                    if (length($f) >= $dir_length and
                        substr($f, 0, $dir_length) eq $dir)
                      {
                        print "d   $f\n";
                        delete $del_files{$f};
                        $repeat_loop = 1;
                      }
                  }

                # If there were any deletions of files and/or
                # directories inside a directory that will be deleted,
                # then restart the entire loop again, because one or
                # more keys have been deleted from %del_files.
                # Equally important is not to stop this loop if no
                # deletions have been done, otherwise later
                # directories that may contain files and directories
                # to be deleted will not be deleted.
                last if $repeat_loop;
              }
          }
      } while ($repeat_loop);

    # What is left are files that are not in any directories to be
    # deleted and directories to be deleted.  To delete the files,
    # deeper files and directories must be deleted first.  Because we
    # have a hash keyed by remaining files and directories to be
    # deleted, instead of trying to figure out which directories and
    # files are contained in other directories, just reverse sort by
    # the path length and then alphabetically.
    my @del_files = sort {length($b) <=> length($a) || $a cmp $b }
                    keys %del_files;
    &filter_renamed_files(\@del_files, \%rename_from_files);
    foreach my $file (@del_files)
      {
        print "D   $file\n";
      }

    # Now change back to the trunk directory and run the svn commands.
    chdir($wc_import_dir_cwd)
      or die "$0: cannot chdir '$wc_import_dir_cwd': $!\n";

    # If any of the added files have the svn:eol-style property set,
    # then pass -b to diff, otherwise diff may fail because the end of
    # lines have changed and the source file and file in the
    # repository will not be identical.
    my @diff_ignore_space_changes;

    if (keys %add_files)
      {
        my @add_files = sort {length($a) <=> length($b) || $a cmp $b}
                        keys %add_files;
        my $target_filename = &make_targets_file(@add_files);
        read_from_process($svn, 'add', '-N', '--targets', $target_filename);
        unlink($target_filename);

        # Add properties on the added files.
        foreach my $add_file (@add_files)
          {
            foreach my $property (@{$add_files{$add_file}{properties}})
              {
                my $property_name  = $property->{name};
                my $property_value = $property->{value};

                if ($property_name eq 'svn:eol-style')
                  {
                    @diff_ignore_space_changes = ('-b');
                  }
                
                # Write the value to a temporary file in case it's multi-line
                my ($handle, $tmpfile) = tempfile(DIR => $temp_dir);
                print $handle $property_value;
                close($handle);

                read_from_process($svn,
                                  'propset',
                                  $property_name,
                                  '--file',
                                  $tmpfile,
                                  $add_file);
              }
          }
      }
    if (@del_files)
      {
        my $target_filename = &make_targets_file(@del_files);
        read_from_process($svn, 'rm', '--targets', $target_filename);
        unlink($target_filename);
      }

    # Go through the list of updated files and check the svn:eol-style
    # property.  If it is set to native, then convert all CR, CRLF and
    # LF's in the file to the native end of line characters.  Also,
    # modify diff's command line so that it will ignore the change in
    # end of line style.
    if (keys %upd_files)
      {
        my @upd_files = sort {length($a) <=> length($b) || $a cmp $b}
                        keys %upd_files;
        foreach my $upd_file (@upd_files)
          {
            my @command = ($svn, 'propget', 'svn:eol-style', $upd_file);
            my @lines = read_from_process(@command);
            next unless @lines;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -