コード例 #1
0
Py::Object pysvn_client::cmd_diff( const Py::Tuple &a_args, const Py::Dict &a_kws )
{
    static argument_description args_desc[] =
    {
    { true,  name_tmp_path },
    { true,  name_url_or_path },
    { false, name_revision1 },
    { false, name_url_or_path2 },
    { false, name_revision2 },
    { false, name_recurse },
    { false, name_ignore_ancestry },
    { false, name_diff_deleted },
#if defined( PYSVN_HAS_CLIENT_DIFF2 )
    { false, name_ignore_content_type },
#endif
#if defined( PYSVN_HAS_CLIENT_DIFF3 )
    { false, name_header_encoding },
    { false, name_diff_options },
#endif
#if defined( PYSVN_HAS_CLIENT_DIFF4 )
    { false, name_depth },
    { false, name_relative_to_dir },
    { false, name_changelists },
#endif
    { false, NULL }
    };
    FunctionArguments args( "diff", args_desc, a_args, a_kws );
    args.check();

    std::string tmp_path( args.getUtf8String( name_tmp_path ) );
    std::string path1( args.getUtf8String( name_url_or_path ) );
    svn_opt_revision_t revision1 = args.getRevision( name_revision1, svn_opt_revision_base );
    std::string path2( args.getUtf8String( name_url_or_path2, path1 ) );
    svn_opt_revision_t revision2 = args.getRevision( name_revision2, svn_opt_revision_working );
#if defined( PYSVN_HAS_CLIENT_DIFF4 )
    svn_depth_t depth = args.getDepth( name_depth, name_recurse, svn_depth_infinity, svn_depth_infinity, svn_depth_files );
#else
    bool recurse = args.getBoolean( name_recurse, true );
#endif
    bool ignore_ancestry = args.getBoolean( name_ignore_ancestry, true );
    bool diff_deleted = args.getBoolean( name_diff_deleted, true );
#if defined( PYSVN_HAS_CLIENT_DIFF2 )
    bool ignore_content_type = args.getBoolean( name_ignore_content_type, false );
#endif

    SvnPool pool( m_context );

#if defined( PYSVN_HAS_CLIENT_DIFF3 )
    std::string header_encoding( args.getUtf8String( name_header_encoding, empty_string ) );
    const char *header_encoding_ptr = APR_LOCALE_CHARSET;
    if( !header_encoding.empty() )
        header_encoding_ptr = header_encoding.c_str();

    apr_array_header_t *options = NULL;
    if( args.hasArg( name_diff_options ) )
    {
        options = arrayOfStringsFromListOfStrings( args.getArg( name_diff_options ), pool );
    }
    else
    {
        options = apr_array_make( pool, 0, sizeof( const char * ) );
    }
#else
    apr_array_header_t *options = apr_array_make( pool, 0, sizeof( const char * ) );
#endif

#if defined( PYSVN_HAS_CLIENT_DIFF4 )
    std::string std_relative_to_dir;
    const char *relative_to_dir = NULL;
    if( args.hasArg( name_relative_to_dir ) )
    {
        std_relative_to_dir = args.getUtf8String( name_relative_to_dir );
        relative_to_dir = std_relative_to_dir.c_str();
    }

    apr_array_header_t *changelists = NULL;

    if( args.hasArg( name_changelists ) )
    {
        changelists = arrayOfStringsFromListOfStrings( args.getArg( name_changelists ), pool );
    }
#endif

    svn_stringbuf_t *stringbuf = NULL;

    try
    {
        std::string norm_tmp_path( svnNormalisedIfPath( tmp_path, pool ) );
        std::string norm_path1( svnNormalisedIfPath( path1, pool ) );
        std::string norm_path2( svnNormalisedIfPath( path2, pool ) );

        checkThreadPermission();

        pysvn_apr_file output_file( pool );
        pysvn_apr_file error_file( pool );

        output_file.open_unique_file( norm_tmp_path );
        error_file.open_unique_file( norm_tmp_path );

        PythonAllowThreads permission( m_context );

#if defined( PYSVN_HAS_CLIENT_DIFF4 )
        svn_error_t *error = svn_client_diff4
            (
            options,
            norm_path1.c_str(), &revision1,
            norm_path2.c_str(), &revision2,
            relative_to_dir,
            depth,
            ignore_ancestry,
            !diff_deleted,
            ignore_content_type,
            header_encoding_ptr,
            output_file.file(),
            error_file.file(),
            changelists,
            m_context,
            pool
            );
#elif defined( PYSVN_HAS_CLIENT_DIFF3 )
        svn_error_t *error = svn_client_diff3
            (
            options,
            norm_path1.c_str(), &revision1,
            norm_path2.c_str(), &revision2,
            recurse,
            ignore_ancestry,
            !diff_deleted,
            ignore_content_type,
            header_encoding_ptr,
            output_file.file(),
            error_file.file(),
            m_context,
            pool
            );
#elif defined( PYSVN_HAS_CLIENT_DIFF2 )
        svn_error_t *error = svn_client_diff2
            (
            options,
            norm_path1.c_str(), &revision1,
            norm_path2.c_str(), &revision2,
            recurse,
            ignore_ancestry,
            !diff_deleted,
            ignore_content_type,
            output_file.file(),
            error_file.file(),
            m_context,
            pool
            );
#else
        svn_error_t *error = svn_client_diff
            (
            options,
            norm_path1.c_str(), &revision1,
            norm_path2.c_str(), &revision2,
            recurse,
            ignore_ancestry,
            !diff_deleted,
            output_file.file(),
            error_file.file(),
            m_context,
            pool
            );
#endif
        permission.allowThisThread();
        if( error != NULL )
            throw SvnException( error );

        output_file.close();

        output_file.open_tmp_file();
        error = svn_stringbuf_from_aprfile( &stringbuf, output_file.file(), pool );
        if( error != NULL )
            throw SvnException( error );
    }
    catch( SvnException &e )
    {
        // use callback error over ClientException
        m_context.checkForError( m_module.client_error );

        throw_client_error( e );
    }

    // cannot convert to Unicode as we have no idea of the encoding of the bytes
    return Py::String( stringbuf->data, (int)stringbuf->len );
}
コード例 #2
0
ファイル: svn.c プロジェクト: patrickpreuss/archivist
int a_svn_diff
(char *device_group, char *device_name, char *configured_by, char *repository_path, 
 char *temp_working_dir, apr_pool_t *apr_pool, apr_pool_t *svn_pool)
/*
*
* diff of a working copy and svn head (for a single file)
*
*/
{

    svn_error_t* err;
    int int_err;
    apr_array_header_t *device_arr;
    apr_file_t *diff_outfile;
    apr_file_t *diff_errfile;
    apr_array_header_t *array;
    struct stat svn_diff_file_info;
    int svn_diff_file_size = 0;

    char temp_svn_path[MAXPATH];
    char full_device_svn_path[MAXPATH];
    char svn_diff_outfname[50]=".";
    char svn_diff_errfname[50]=".";

    svn_client_ctx_t* context;

    svn_error_t *svn_err;

    temp_svn_path[0] = 0x0;
    full_device_svn_path[0] = 0x0;

    strcat(temp_svn_path,temp_working_dir);

    strcat(svn_diff_outfname,device_name);
    strcat(svn_diff_outfname,".diff.tmp");

    strcat(svn_diff_errfname,device_name);
    strcat(svn_diff_errfname,".diff.err.tmp");

    /* if device is in the device group - add group name to the SVN diff path: */

    if(strstr(device_group,"none"))
     snprintf(full_device_svn_path,MAXPATH,"%s/%s",repository_path,device_name);
    else
     snprintf(full_device_svn_path,MAXPATH,"%s/%s/%s",repository_path,device_group,device_name);

    apr_file_open(&diff_outfile, svn_diff_outfname, (APR_READ | APR_WRITE | APR_CREATE ),
                            ( APR_FPROT_UREAD | APR_FPROT_UWRITE |
                              APR_FPROT_GREAD | APR_FPROT_WREAD ),
                                        apr_pool);

    apr_file_open(&diff_errfile, svn_diff_errfname, (APR_READ | APR_WRITE | APR_CREATE ),
                            ( APR_FPROT_UREAD | APR_FPROT_UWRITE |
                              APR_FPROT_GREAD | APR_FPROT_WREAD ),
                                        apr_pool);

    svn_err = svn_client_create_context( &context, svn_pool );
    if(svn_err){a_logmsg("%s: svn error: %s",device_name,svn_err->message);
                a_debug_info2(DEBUGLVL5,"a_svn_diff: svn error: %s",svn_err->message); 
                return -1;}


    svn_opt_revision_t pegrevision;
    pegrevision.kind = svn_opt_revision_unspecified;

    svn_opt_revision_t revision1;
    revision1.kind = svn_opt_revision_working;

    svn_opt_revision_t revision2;
    revision2.kind = svn_opt_revision_head;

    strcat(temp_svn_path,"/");
    strcat(temp_svn_path,device_name);

    array = apr_array_make (apr_pool, 0, sizeof (const char *));

    svn_err = svn_client_diff4(array,
                             svn_path_canonicalize(temp_svn_path,apr_pool),
                             &revision1,
                             svn_path_canonicalize(full_device_svn_path,apr_pool),
                             &revision2,
                             NULL,
                             svn_depth_empty,
                             FALSE,
                             TRUE,
                             FALSE,
                             APR_LOCALE_CHARSET,
                             diff_outfile,
                             diff_errfile,
                             NULL,
                             context,
                             svn_pool);
    if(svn_err){
                a_logmsg("%s: svn error: %s",device_name,svn_err->message);
                a_debug_info2(DEBUGLVL5,"a_svn_diff: svn error: %s",svn_err->message); 
                return -1;
               }


    apr_file_close(diff_errfile);
    remove(svn_diff_errfname);
    apr_file_close(diff_outfile);

    if( (stat(svn_diff_outfname,&svn_diff_file_info)) == -1)
     a_debug_info2(DEBUGLVL5,"a_svn_diff: cannot stat %s!",svn_diff_outfname);

    svn_diff_file_size = (int)svn_diff_file_info.st_size; 

    if((G_config_info.keep_changelog) && (svn_diff_file_size > 0)) 
      if(!a_add_changelog_entry(svn_diff_outfname, svn_diff_file_size, device_name, configured_by))
       {
        a_logmsg("a_svn_diff: %s: cannot write changelog entry!",device_name);
        a_debug_info2(DEBUGLVL5,"a_svn_diff: cannot write changelog entry!",device_name);
       }

    /* what we are returning here, is the length of a diff file */
    /* if it is nonzero - revisions differ: */

    remove(svn_diff_outfname);
    return svn_diff_file_size;  

}
コード例 #3
0
ファイル: swig_svn.c プロジェクト: aryx/fork-ocsigen
/* fonction simulant la commande svn diff */
apr_array_header_t *svn_support_diff_call(char *rep_path,
                                          char *filename,
                                          int revision1,
                                          int revision2,
                                          apr_pool_t* subpool)
{
  svn_error_t *err;
  apr_file_t *outfile;
  apr_file_t *errfile;
  apr_status_t rv;
  svn_opt_revision_t rev1;
  svn_opt_revision_t rev2;
 
  // -- Initialisation du tableau et du buffer de résultats -- 
  apr_array_header_t *list_result = apr_array_make(subpool, 1, sizeof (const char *));
  svn_stringbuf_t *res = svn_stringbuf_create("",subpool);	
  
  // -- Initialisation des chemins des fichiers --
  const svn_stringbuf_t *slash = svn_stringbuf_create("/",subpool);
  const svn_stringbuf_t *filepath = svn_stringbuf_create(filename,subpool);
  svn_stringbuf_t *path = svn_stringbuf_create(rep_path,subpool);
  if (strcmp(filename,"") != 0) {
    svn_stringbuf_appendstr(path,slash);
    svn_stringbuf_appendstr(path,filepath);
  }
  
  // -- Initialisation des revisions --
  rev1.kind = rev2.kind = svn_opt_revision_number;
  rev1.value.number=revision1;
  rev2.value.number=revision2;
  
  // -- Initialisation des fichiers d'output --
  if ((rv = apr_file_open_stdout(&outfile,subpool)) != APR_SUCCESS) {
    svn_pool_destroy(subpool);
    return NULL;
  }
  if ((rv = apr_file_open_stdout(&errfile,subpool)) != APR_SUCCESS) {
    svn_pool_destroy(subpool);
    return NULL;
  }
  const apr_array_header_t *diff_options =  apr_array_make(subpool, 1, sizeof (const char *));
  //apr_file_t *write_end;
  //apr_file_t *read_end;
  //apr_file_pipe_create(&write_end,&read_end,subpool);
  int tube[2];
  pipe(tube);
  switch(fork()){
  case -1: 
    perror("fork");
    svn_pool_destroy(subpool);
    return NULL;
  case 0:
    //apr_file_close(read_end);
    //apr_file_dup2(outfile,write_end,subpool);
    close(tube[0]);
    dup2(tube[1],STDOUT_FILENO);
    err = svn_client_diff4(diff_options,
			   path->data,
			   &rev1,
			   path->data,
			   &rev2,
			   NULL,
			   svn_depth_infinity,
			   TRUE,// ignore_ancestry
			   TRUE,// no_diff_deleted
			   FALSE, // ignore_content_type
			   SVN_APR_LOCALE_CHARSET,
			   outfile,
			   errfile,
			   NULL,
			   ctx,
			   subpool);
    if (err) {
      svn_handle_error2 (err, stderr, FALSE, "svn_support_diff: ");
      svn_pool_destroy(subpool);
      return NULL;
    }
    exit(0);
  }
  //apr_file_close(write_end);
  close(tube[1]);
  int buf_size = 4096;
  char buf[buf_size];
  int rc;
  const svn_stringbuf_t *tmp;
  while((rc=read(tube[0],buf,buf_size))>0){//(rv=apr_file_gets(buf,buf_size,read_end))){
      //if(APR_STATUS_IS_EOF(rv))
      //break;
    buf[rc]='\0';
    tmp = svn_stringbuf_create(buf,subpool);
    svn_stringbuf_appendstr(res,tmp);
    //*(char **)apr_array_push(list_result) = buf;
  }
  wait(NULL);
  svn_cstring_split_endline_append(list_result,res->data,subpool);
  svn_pool_destroy(subpool);
  return list_result;
}