~ubuntu-branches/ubuntu/edgy/pysvn/edgy

« back to all changes in this revision

Viewing changes to Source/pysvn_client.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2006-03-07 14:08:44 UTC
  • mto: This revision was merged to the branch mainline in revision 5.
  • Revision ID: james.westby@ubuntu.com-20060307140844-xey4ygiqdrexvq0s
Tags: upstream-1.4.1
ImportĀ upstreamĀ versionĀ 1.4.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
//
2
2
// ====================================================================
3
 
// (c) 2003-2005 Barry A Scott.  All rights reserved.
 
3
// (c) 2003-2006 Barry A Scott.  All rights reserved.
4
4
//
5
5
// This software is licensed as described in the file LICENSE.txt,
6
6
// which you should have received as part of this distribution.
32
32
static const char name_callback_get_log_message[] = "callback_get_log_message";
33
33
static const char name_callback_get_login[] = "callback_get_login";
34
34
static const char name_callback_notify[] = "callback_notify";
 
35
static const char name_callback_progress[] = "callback_progress";
35
36
static const char name_callback_ssl_client_cert_password_prompt[] = "callback_ssl_client_cert_password_prompt";
36
37
static const char name_callback_ssl_client_cert_prompt[] = "callback_ssl_client_cert_prompt";
37
38
static const char name_callback_ssl_server_prompt[] = "callback_ssl_server_prompt";
53
54
static const char name_force[] = "force";
54
55
static const char name_from_url[] = "from_url";
55
56
static const char name_get_all[] = "get_all";
 
57
static const char name_header_encoding[] = "header_encoding";
56
58
static const char name_ignore[] = "ignore";
57
59
static const char name_ignore_ancestry[] = "ignore_ancestry";
58
60
static const char name_ignore_content_type[] = "ignore_content_type";
59
61
static const char name_ignore_externals[] = "ignore_externals";
 
62
static const char name_keep_locks[] = "keep_locks";
60
63
static const char name_kind[] = "kind";
61
64
static const char name_last_author[] = "last_author";
62
65
static const char name_lock[] = "lock";
 
66
static const char name_limit[] = "limit";
63
67
static const char name_line[] = "line";
64
68
static const char name_local_path[] = "local_path";
65
69
static const char name_log_message[] = "log_message";
78
82
static const char name_revision1[] = "revision1";
79
83
static const char name_revision2[] = "revision2";
80
84
static const char name_size[] = "size";
 
85
static const char name_skip_checks[] = "skip_checks";
81
86
static const char name_src_revision[] = "src_revision";
82
87
static const char name_src_url_or_path[] = "src_url_or_path";
83
88
static const char name_strict_node_history[] = "strict_node_history";
133
138
        return m_context.m_pyfn_GetLogin;
134
139
    if( name == name_callback_notify )
135
140
        return m_context.m_pyfn_Notify;
 
141
#ifdef PYSVN_HAS_CONTEXT_PROGRESS
 
142
    if( name == name_callback_progress )
 
143
        return m_context.m_pyfn_Progress;
 
144
#endif
136
145
    if( name == name_callback_cancel )
137
146
        return m_context.m_pyfn_Cancel;
138
147
    if( name == name_callback_get_log_message )
165
174
        set_callable( m_context.m_pyfn_GetLogin, value );
166
175
    else if( name == name_callback_notify )
167
176
        set_callable( m_context.m_pyfn_Notify, value );
 
177
#ifdef PYSVN_HAS_CONTEXT_PROGRESS
 
178
    else if( name == name_callback_progress )
 
179
        set_callable( m_context.m_pyfn_Progress, value );
 
180
#endif
168
181
    else if( name == name_callback_cancel )
169
182
        set_callable( m_context.m_pyfn_Cancel, value );
170
183
    else if( name == name_callback_get_log_message )
208
221
#ifdef PYSVN_HAS_CLIENT_ADD2
209
222
    { false, name_force },
210
223
#endif
 
224
#ifdef PYSVN_HAS_CLIENT_ADD3
 
225
    { false, name_ignore },
 
226
#endif
211
227
    { false, NULL }
212
228
    };
213
229
    FunctionArguments args( "add", args_desc, a_args, a_kws );
217
233
 
218
234
    bool recurse = args.getBoolean( name_recurse, true );
219
235
#ifdef PYSVN_HAS_CLIENT_ADD2
220
 
    bool force = args.getBoolean( name_force, true );
 
236
    bool force = args.getBoolean( name_force, false );
 
237
#endif
 
238
#ifdef PYSVN_HAS_CLIENT_ADD3
 
239
    bool ignore = args.getBoolean( name_ignore, true );
221
240
#endif
222
241
 
223
242
    SvnPool pool( m_context );
234
253
 
235
254
            SvnPool pool( m_context );
236
255
 
237
 
#ifdef PYSVN_HAS_CLIENT_ADD2
 
256
#if defined( PYSVN_HAS_CLIENT_ADD3 )
 
257
            svn_error_t * error = svn_client_add3
 
258
                (
 
259
                norm_path.c_str(),
 
260
                recurse,
 
261
                force,
 
262
                !ignore,
 
263
                m_context,
 
264
                pool
 
265
                );
 
266
#elif defined( PYSVN_HAS_CLIENT_ADD2 )
238
267
            svn_error_t * error = svn_client_add2
239
268
                (
240
269
                norm_path.c_str(),
331
360
    { true,  name_url_or_path },
332
361
    { false, name_revision_start },
333
362
    { false, name_revision_end },
 
363
#ifdef PYSVN_HAS_CLIENT_ANNOTATE2
 
364
    { false, name_peg_revision },
 
365
#endif
334
366
    { false, NULL }
335
367
    };
336
368
    FunctionArguments args( "annotate", args_desc, a_args, a_kws );
339
371
    std::string path( args.getUtf8String( name_url_or_path, empty_string ) );
340
372
    svn_opt_revision_t revision_start = args.getRevision( name_revision_start, svn_opt_revision_number );
341
373
    svn_opt_revision_t revision_end = args.getRevision( name_revision_end, svn_opt_revision_head );
342
 
 
 
374
#ifdef PYSVN_HAS_CLIENT_ANNOTATE2
 
375
    svn_opt_revision_t peg_revision = args.getRevision( name_peg_revision, revision_end );
 
376
#endif
343
377
    SvnPool pool( m_context );
344
378
    std::list<AnnotatedLineInfo> all_entries;
345
379
 
351
385
 
352
386
        PythonAllowThreads permission( m_context );
353
387
 
 
388
#ifdef PYSVN_HAS_CLIENT_ANNOTATE2
 
389
        svn_error_t *error = svn_client_blame2
 
390
            (
 
391
            norm_path.c_str(),
 
392
            &peg_revision,
 
393
            &revision_start,
 
394
            &revision_end,
 
395
            annotate_receiver,
 
396
            &all_entries,
 
397
            m_context,
 
398
            pool
 
399
            );
 
400
#else
354
401
        svn_error_t *error = svn_client_blame
355
402
            (
356
403
            norm_path.c_str(),
361
408
            m_context,
362
409
            pool
363
410
            );
364
 
 
 
411
#endif
365
412
        if( error != NULL )
366
413
        {
367
414
            throw SvnException( error );
386
433
        Py::Dict entry_dict;
387
434
        entry_dict[name_author] = Py::String( entry.m_author, name_utf8 );
388
435
        entry_dict[name_date] = Py::String( entry.m_date );
389
 
        entry_dict[name_line] = Py::String( entry.m_line, name_utf8 );
 
436
        entry_dict[name_line] = Py::String( entry.m_line );
390
437
        entry_dict[name_number] = Py::Int( long( entry.m_line_no ) );
391
438
        entry_dict[name_revision] = Py::asObject( new pysvn_revision( svn_opt_revision_number, 0, entry.m_revision ) );
392
439
 
402
449
    {
403
450
    { true,  name_url_or_path },
404
451
    { false, name_revision },
 
452
#ifdef PYSVN_HAS_CLIENT_CAT2
 
453
    { false, name_peg_revision },
 
454
#endif
405
455
    { false, NULL }
406
456
    };
407
457
    FunctionArguments args( "cat", args_desc, a_args, a_kws );
409
459
 
410
460
    std::string path( args.getUtf8String( name_url_or_path ) );
411
461
    svn_opt_revision_t revision = args.getRevision( name_revision, svn_opt_revision_head );
 
462
#ifdef PYSVN_HAS_CLIENT_CAT2
 
463
    svn_opt_revision_t peg_revision = args.getRevision( name_peg_revision, revision );
 
464
#endif
412
465
 
413
466
    SvnPool pool( m_context );
414
467
 
422
475
        checkThreadPermission();
423
476
 
424
477
        PythonAllowThreads permission( m_context );
 
478
#ifdef PYSVN_HAS_CLIENT_CAT2
 
479
        svn_error_t *error = svn_client_cat2
 
480
            (
 
481
            stream,
 
482
            norm_path.c_str(),
 
483
            &peg_revision,
 
484
            &revision,
 
485
            m_context,
 
486
            pool
 
487
            );
 
488
#else
425
489
        svn_error_t *error = svn_client_cat
426
490
            (
427
491
            stream,
428
 
            norm_path.c_str (),
 
492
            norm_path.c_str(),
429
493
            &revision,
430
494
            m_context,
431
495
            pool
432
496
            );
 
497
#endif
433
498
 
434
499
        if (error != 0)
435
500
            throw SvnException (error);
447
512
    return Py::String( stringbuf->data, (int)stringbuf->len );
448
513
}
449
514
 
 
515
Py::Object pysvn_client::cmd_checkin( const Py::Tuple &a_args, const Py::Dict &a_kws )
 
516
{
 
517
    static argument_description args_desc[] =
 
518
    {
 
519
    { true,  name_path },
 
520
    { true,  name_log_message },
 
521
    { false, name_recurse },
 
522
#if defined( PYSVN_HAS_CLIENT_COMMIT2 )
 
523
    { false, name_keep_locks },
 
524
#endif
 
525
    { false, NULL }
 
526
    };
 
527
    FunctionArguments args( "checkin", args_desc, a_args, a_kws );
 
528
    args.check();
 
529
 
 
530
    SvnPool pool( m_context );
 
531
    pysvn_commit_info_t *commit_info = NULL;
 
532
 
 
533
    apr_array_header_t *targets = targetsFromStringOrList( args.getArg( name_path ), pool );
 
534
 
 
535
    std::string type_error_message;
 
536
    try
 
537
    {
 
538
        type_error_message = "expecting string for message (arg 2)";
 
539
 
 
540
        std::string message( args.getUtf8String( name_log_message ) );
 
541
 
 
542
        type_error_message = "expecting boolean for recurse keyword arg";
 
543
        bool recurse = args.getBoolean( name_recurse, true );
 
544
 
 
545
#ifdef PYSVN_HAS_CLIENT_COMMIT2
 
546
        type_error_message = "expecting boolean for keep_locks keyword arg";
 
547
        bool keep_locks = args.getBoolean( name_keep_locks, true );
 
548
#endif
 
549
 
 
550
        try
 
551
        {
 
552
            checkThreadPermission();
 
553
 
 
554
            PythonAllowThreads permission( m_context );
 
555
 
 
556
            m_context.setLogMessage( message );
 
557
 
 
558
#if defined( PYSVN_HAS_CLIENT_COMMIT3 )
 
559
            svn_error_t *error = svn_client_commit3
 
560
                (
 
561
                &commit_info,   // commit info type changed
 
562
                targets,
 
563
                recurse,
 
564
                keep_locks,
 
565
                m_context,
 
566
                pool
 
567
                );
 
568
#elif defined( PYSVN_HAS_CLIENT_COMMIT2 )
 
569
            svn_error_t *error = svn_client_commit2
 
570
                (
 
571
                &commit_info,
 
572
                targets,
 
573
                recurse,
 
574
                keep_locks,
 
575
                m_context,
 
576
                pool
 
577
                );
 
578
#else
 
579
            svn_error_t *error = svn_client_commit
 
580
                (
 
581
                &commit_info,
 
582
                targets,
 
583
                !recurse,       // non recursive
 
584
                m_context,
 
585
                pool
 
586
                );
 
587
#endif
 
588
            if( error != NULL )
 
589
                throw SvnException( error );
 
590
        }
 
591
        catch( SvnException &e )
 
592
        {
 
593
            // use callback error over ClientException
 
594
            m_context.checkForError( m_module.client_error );
 
595
 
 
596
            throw_client_error( e );
 
597
        }
 
598
    }
 
599
    catch( Py::TypeError & )
 
600
    {
 
601
        throw Py::TypeError( type_error_message );
 
602
    }
 
603
 
 
604
    return toObject( commit_info );
 
605
}
 
606
 
450
607
Py::Object pysvn_client::cmd_checkout( const Py::Tuple &a_args, const Py::Dict &a_kws )
451
608
{
452
609
    static argument_description args_desc[] =
469
626
    bool recurse = args.getBoolean( name_recurse, true );
470
627
    svn_opt_revision_t revision = args.getRevision( name_revision, svn_opt_revision_head );
471
628
#ifdef PYSVN_HAS_CLIENT_CHECKOUT2
472
 
    svn_opt_revision_t peg_revision = args.getRevision( name_peg_revision, svn_opt_revision_unspecified );
 
629
    svn_opt_revision_t peg_revision = args.getRevision( name_peg_revision, revision );
473
630
    bool ignore_externals = args.getBoolean( name_ignore_externals, false );
474
631
#endif
475
632
    SvnPool pool( m_context );
560
717
    return Py::Nothing();
561
718
}
562
719
 
563
 
Py::Object pysvn_client::cmd_checkin( const Py::Tuple &a_args, const Py::Dict &a_kws )
564
 
{
565
 
    static argument_description args_desc[] =
566
 
    {
567
 
    { true,  name_path },
568
 
    { true,  name_log_message },
569
 
    { false, name_recurse },
570
 
    { false, NULL }
571
 
    };
572
 
    FunctionArguments args( "checkin", args_desc, a_args, a_kws );
573
 
    args.check();
574
 
 
575
 
    SvnPool pool( m_context );
576
 
    svn_client_commit_info_t *commit_info = NULL;
577
 
 
578
 
    apr_array_header_t *targets = targetsFromStringOrList( args.getArg( name_path ), pool );
579
 
 
580
 
    std::string type_error_message;
581
 
    try
582
 
    {
583
 
        type_error_message = "expecting string for message (arg 2)";
584
 
 
585
 
        std::string message( args.getUtf8String( name_log_message ) );
586
 
 
587
 
        type_error_message = "expecting boolean for recurse keyword arg";
588
 
        bool recurse = args.getBoolean( name_recurse, true );
589
 
 
590
 
 
591
 
        try
592
 
        {
593
 
            checkThreadPermission();
594
 
 
595
 
            PythonAllowThreads permission( m_context );
596
 
 
597
 
            m_context.setLogMessage( message );
598
 
 
599
 
            svn_error_t *error = svn_client_commit
600
 
                (
601
 
                &commit_info,
602
 
                targets,
603
 
                !recurse,        // non recursive
604
 
                m_context,
605
 
                pool
606
 
                );
607
 
            if( error != NULL )
608
 
                throw SvnException( error );
609
 
        }
610
 
        catch( SvnException &e )
611
 
        {
612
 
            // use callback error over ClientException
613
 
            m_context.checkForError( m_module.client_error );
614
 
 
615
 
            throw_client_error( e );
616
 
        }
617
 
    }
618
 
    catch( Py::TypeError & )
619
 
    {
620
 
        throw Py::TypeError( type_error_message );
621
 
    }
622
 
 
623
 
    return toObject( commit_info );
624
 
}
625
 
 
626
720
Py::Object pysvn_client::cmd_copy( const Py::Tuple &a_args, const Py::Dict &a_kws )
627
721
{
628
722
    static argument_description args_desc[] =
636
730
    args.check();
637
731
 
638
732
    SvnPool pool( m_context );
639
 
    svn_client_commit_info_t *commit_info = NULL;
 
733
    pysvn_commit_info_t *commit_info = NULL;
640
734
 
641
735
    std::string type_error_message;
642
736
    try
659
753
 
660
754
            PythonAllowThreads permission( m_context );
661
755
 
 
756
#if defined( PYSVN_HAS_CLIENT_COPY2 )
 
757
            svn_error_t *error = svn_client_copy2
 
758
                (
 
759
                &commit_info,       // commit info type changed
 
760
                norm_src_path.c_str(),
 
761
                &revision,
 
762
                norm_dest_path.c_str(),
 
763
                m_context,
 
764
                pool
 
765
                );
 
766
#else
662
767
            svn_error_t *error = svn_client_copy
663
768
                (
664
769
                &commit_info,
668
773
                m_context,
669
774
                pool
670
775
                );
671
 
 
 
776
#endif
672
777
            if( error != NULL )
673
778
                throw SvnException( error );
674
779
        }
772
877
#ifdef PYSVN_HAS_CLIENT_DIFF2
773
878
    { false, name_ignore_content_type },
774
879
#endif
 
880
#if defined( PYSVN_HAS_CLIENT_DIFF3 )
 
881
    { false, name_header_encoding },
 
882
#endif
775
883
    { false, NULL }
776
884
    };
777
885
    FunctionArguments args( "diff", args_desc, a_args, a_kws );
788
896
#ifdef PYSVN_HAS_CLIENT_DIFF2
789
897
    bool ignore_content_type = args.getBoolean( name_ignore_content_type, false );
790
898
#endif
 
899
#if defined( PYSVN_HAS_CLIENT_DIFF3 )
 
900
    std::string header_encoding( args.getUtf8String( name_header_encoding, empty_string ) );
 
901
    const char *header_encoding_ptr = APR_LOCALE_CHARSET;
 
902
    if( !header_encoding.empty() )
 
903
        header_encoding_ptr = header_encoding.c_str();
 
904
#endif
791
905
 
792
906
    SvnPool pool( m_context );
793
907
 
810
924
 
811
925
        apr_array_header_t *options = apr_array_make( pool, 0, 0 );
812
926
 
813
 
#ifdef PYSVN_HAS_CLIENT_DIFF2
 
927
#if defined( PYSVN_HAS_CLIENT_DIFF3 )
 
928
        svn_error_t *error = svn_client_diff3
 
929
            (
 
930
            options,
 
931
            norm_path1.c_str(), &revision1,
 
932
            norm_path2.c_str(), &revision2,
 
933
            recurse,
 
934
            ignore_ancestry,
 
935
            !diff_deleted,
 
936
            ignore_content_type,
 
937
            header_encoding_ptr,
 
938
            output_file.file(),
 
939
            error_file.file(),
 
940
            m_context,
 
941
            pool
 
942
            );
 
943
#elif defined( PYSVN_HAS_CLIENT_DIFF2 )
814
944
        svn_error_t *error = svn_client_diff2
815
945
            (
816
946
            options,
862
992
    return Py::String( stringbuf->data, (int)stringbuf->len );
863
993
}
864
994
 
 
995
#ifdef PYSVN_HAS_CLIENT_DIFF_PEG
 
996
Py::Object pysvn_client::cmd_diff_peg( const Py::Tuple &a_args, const Py::Dict &a_kws )
 
997
{
 
998
    static argument_description args_desc[] =
 
999
    {
 
1000
    { true,  name_tmp_path },
 
1001
    { true,  name_url_or_path },
 
1002
    { false, name_peg_revision },
 
1003
    { false, name_revision_start },
 
1004
    { false, name_revision_end },
 
1005
    { false, name_recurse },
 
1006
    { false, name_ignore_ancestry },
 
1007
    { false, name_diff_deleted },
 
1008
#ifdef PYSVN_HAS_CLIENT_DIFF_PEG2
 
1009
    { false, name_ignore_content_type },
 
1010
#endif
 
1011
#if defined( PYSVN_HAS_CLIENT_DIFF_PEG3 )
 
1012
    { false, name_header_encoding },
 
1013
#endif
 
1014
    { false, NULL }
 
1015
    };
 
1016
    FunctionArguments args( "diff", args_desc, a_args, a_kws );
 
1017
    args.check();
 
1018
 
 
1019
    std::string tmp_path( args.getUtf8String( name_tmp_path ) );
 
1020
    std::string path( args.getUtf8String( name_url_or_path ) );
 
1021
    svn_opt_revision_t revision_start = args.getRevision( name_revision1, svn_opt_revision_base );
 
1022
    svn_opt_revision_t revision_end = args.getRevision( name_revision2, svn_opt_revision_working );
 
1023
    svn_opt_revision_t peg_revision = args.getRevision( name_peg_revision, revision_end );
 
1024
    bool recurse = args.getBoolean( name_recurse, true );
 
1025
    bool ignore_ancestry = args.getBoolean( name_ignore_ancestry, true );
 
1026
    bool diff_deleted = args.getBoolean( name_diff_deleted, true );
 
1027
#ifdef PYSVN_HAS_CLIENT_DIFF_PEG2
 
1028
    bool ignore_content_type = args.getBoolean( name_ignore_content_type, false );
 
1029
#endif
 
1030
#if defined( PYSVN_HAS_CLIENT_DIFF_PEG3 )
 
1031
    std::string header_encoding( args.getUtf8String( name_header_encoding, empty_string ) );
 
1032
    const char *header_encoding_ptr = APR_LOCALE_CHARSET;
 
1033
    if( !header_encoding.empty() )
 
1034
        header_encoding_ptr = header_encoding.c_str();
 
1035
#endif
 
1036
 
 
1037
    SvnPool pool( m_context );
 
1038
 
 
1039
    svn_stringbuf_t *stringbuf = NULL;
 
1040
 
 
1041
    try
 
1042
    {
 
1043
        std::string norm_tmp_path( svnNormalisedIfPath( tmp_path, pool ) );
 
1044
        std::string norm_path( svnNormalisedIfPath( path, pool ) );
 
1045
 
 
1046
        checkThreadPermission();
 
1047
 
 
1048
        PythonAllowThreads permission( m_context );
 
1049
        pysvn_apr_file output_file( pool );
 
1050
        pysvn_apr_file error_file( pool );
 
1051
 
 
1052
        output_file.open_unique_file( norm_tmp_path );
 
1053
        error_file.open_unique_file( norm_tmp_path );
 
1054
 
 
1055
        apr_array_header_t *options = apr_array_make( pool, 0, 0 );
 
1056
 
 
1057
#if defined( PYSVN_HAS_CLIENT_DIFF_PEG3 )
 
1058
        svn_error_t *error = svn_client_diff_peg3
 
1059
            (
 
1060
            options,
 
1061
            norm_path.c_str(),
 
1062
            &peg_revision,
 
1063
            &revision_start,
 
1064
            &revision_end,
 
1065
            recurse,
 
1066
            ignore_ancestry,
 
1067
            !diff_deleted,
 
1068
            ignore_content_type,
 
1069
            header_encoding_ptr,
 
1070
            output_file.file(),
 
1071
            error_file.file(),
 
1072
            m_context,
 
1073
            pool
 
1074
            );
 
1075
#elif defined( PYSVN_HAS_CLIENT_DIFF_PEG2 )
 
1076
        svn_error_t *error = svn_client_diff_peg2
 
1077
            (
 
1078
            options,
 
1079
            norm_path.c_str(),
 
1080
            &peg_revision,
 
1081
            &revision_start,
 
1082
            &revision_end,
 
1083
            recurse,
 
1084
            ignore_ancestry,
 
1085
            !diff_deleted,
 
1086
            ignore_content_type,
 
1087
            output_file.file(),
 
1088
            error_file.file(),
 
1089
            m_context,
 
1090
            pool
 
1091
            );
 
1092
#else
 
1093
        svn_error_t *error = svn_client_diff_peg
 
1094
            (
 
1095
            options,
 
1096
            norm_path.c_str(),
 
1097
            &peg_revision,
 
1098
            &revision_start,
 
1099
            &revision_end,
 
1100
            recurse,
 
1101
            ignore_ancestry,
 
1102
            !diff_deleted,
 
1103
            output_file.file(),
 
1104
            error_file.file(),
 
1105
            m_context,
 
1106
            pool
 
1107
            );
 
1108
#endif
 
1109
        if( error != NULL )
 
1110
            throw SvnException( error );
 
1111
 
 
1112
        output_file.close();
 
1113
 
 
1114
        output_file.open_tmp_file();
 
1115
        error = svn_stringbuf_from_aprfile( &stringbuf, output_file.file(), pool );
 
1116
        if( error != NULL )
 
1117
            throw SvnException( error );
 
1118
    }
 
1119
    catch( SvnException &e )
 
1120
    {
 
1121
        // use callback error over ClientException
 
1122
        m_context.checkForError( m_module.client_error );
 
1123
 
 
1124
        throw_client_error( e );
 
1125
    }
 
1126
 
 
1127
    // cannot convert to Unicode as we have no idea of the encoding of the bytes
 
1128
    return Py::String( stringbuf->data, (int)stringbuf->len );
 
1129
}
 
1130
#endif
 
1131
 
865
1132
Py::Object pysvn_client::cmd_export( const Py::Tuple &a_args, const Py::Dict &a_kws )
866
1133
{
867
1134
    static argument_description args_desc[] =
873
1140
#ifdef PYSVN_HAS_CLIENT_EXPORT2
874
1141
    { false, name_native_eol },
875
1142
#endif
 
1143
#ifdef PYSVN_HAS_CLIENT_EXPORT3
 
1144
    { false, name_ignore_externals },
 
1145
    { false, name_recurse },
 
1146
    { false, name_peg_revision },
 
1147
#endif
876
1148
    { false, NULL }
877
1149
    };
878
1150
    FunctionArguments args( "export", args_desc, a_args, a_kws );
910
1182
        }
911
1183
    }
912
1184
#endif
 
1185
#ifdef PYSVN_HAS_CLIENT_EXPORT3
 
1186
    bool recurse = args.getBoolean( name_recurse, true );
 
1187
    bool ignore_externals = args.getBoolean( name_ignore_externals, false );
 
1188
    svn_opt_revision_t peg_revision = args.getRevision( name_peg_revision, revision );
 
1189
#endif
913
1190
 
914
1191
    svn_revnum_t revnum = 0;
915
1192
 
923
1200
 
924
1201
        PythonAllowThreads permission( m_context );
925
1202
 
 
1203
#ifdef PYSVN_HAS_CLIENT_EXPORT3
 
1204
        svn_error_t * error = svn_client_export3
 
1205
            (
 
1206
            &revnum,
 
1207
            norm_src_path.c_str(),
 
1208
            dest_path.c_str(),
 
1209
            &peg_revision,
 
1210
            &revision,
 
1211
            force,
 
1212
            ignore_externals,
 
1213
            recurse,
 
1214
            native_eol,
 
1215
            m_context,
 
1216
            pool
 
1217
            );
 
1218
#else
926
1219
#ifdef PYSVN_HAS_CLIENT_EXPORT2
927
1220
        svn_error_t * error = svn_client_export2
928
1221
            (
947
1240
            pool
948
1241
            );
949
1242
#endif
 
1243
#endif
950
1244
        if( error != NULL )
951
1245
            throw SvnException( error );
952
1246
    }
962
1256
}
963
1257
 
964
1258
 
 
1259
Py::Object pysvn_client::cmd_import( const Py::Tuple &a_args, const Py::Dict &a_kws )
 
1260
{
 
1261
    static argument_description args_desc[] =
 
1262
    {
 
1263
    { true,  name_path },
 
1264
    { true,  name_url },
 
1265
    { true,  name_log_message },
 
1266
    { false, name_recurse },
 
1267
#ifdef PYSVN_HAS_CLIENT_IMPORT2
 
1268
    { false, name_ignore },
 
1269
#endif
 
1270
    { false, NULL }
 
1271
    };
 
1272
    FunctionArguments args( "import_", args_desc, a_args, a_kws );
 
1273
    args.check();
 
1274
 
 
1275
    std::string path( args.getUtf8String( name_path ) );
 
1276
    std::string url( args.getUtf8String( name_url ) );
 
1277
    std::string message( args.getUtf8String( name_log_message ) );
 
1278
 
 
1279
    bool recurse = args.getBoolean( name_recurse, true );
 
1280
#ifdef PYSVN_HAS_CLIENT_IMPORT2
 
1281
    bool ignore = args.getBoolean( name_ignore, false );
 
1282
#endif
 
1283
 
 
1284
    SvnPool pool( m_context );
 
1285
    pysvn_commit_info_t *commit_info = NULL;
 
1286
 
 
1287
    try
 
1288
    {
 
1289
        std::string norm_path( svnNormalisedIfPath( path, pool ) );
 
1290
 
 
1291
        checkThreadPermission();
 
1292
 
 
1293
        PythonAllowThreads permission( m_context );
 
1294
 
 
1295
        m_context.setLogMessage( message.c_str() );
 
1296
 
 
1297
#if defined( PYSVN_HAS_CLIENT_IMPORT2 )
 
1298
        svn_error_t *error = svn_client_import2
 
1299
            (
 
1300
            &commit_info,       // changed type
 
1301
            norm_path.c_str(),
 
1302
            url.c_str(),
 
1303
            !recurse,           // non_recursive
 
1304
            !ignore,
 
1305
            m_context,
 
1306
            pool
 
1307
            );
 
1308
#else
 
1309
        svn_error_t *error = svn_client_import
 
1310
            (
 
1311
            &commit_info,
 
1312
            norm_path.c_str(),
 
1313
            url.c_str(),
 
1314
            !recurse,           // non_recursive
 
1315
            m_context,
 
1316
            pool
 
1317
            );
 
1318
#endif
 
1319
        if( error != NULL )
 
1320
            throw SvnException( error );
 
1321
    }
 
1322
    catch( SvnException &e )
 
1323
    {
 
1324
        // use callback error over ClientException
 
1325
        m_context.checkForError( m_module.client_error );
 
1326
 
 
1327
        throw_client_error( e );
 
1328
    }
 
1329
 
 
1330
    return toObject( commit_info );
 
1331
}
 
1332
 
 
1333
Py::Object pysvn_client::cmd_info( const Py::Tuple &a_args, const Py::Dict &a_kws )
 
1334
{
 
1335
    static argument_description args_desc[] =
 
1336
    {
 
1337
    { true,  name_path },
 
1338
    { false, NULL }
 
1339
    };
 
1340
    FunctionArguments args( "info", args_desc, a_args, a_kws );
 
1341
    args.check();
 
1342
 
 
1343
    std::string path( args.getUtf8String( name_path ) );
 
1344
 
 
1345
    SvnPool pool( m_context );
 
1346
    try
 
1347
    {
 
1348
        std::string norm_path( svnNormalisedIfPath( path, pool ) );
 
1349
 
 
1350
        checkThreadPermission();
 
1351
 
 
1352
        PythonAllowThreads permission( m_context );
 
1353
 
 
1354
        svn_wc_adm_access_t *adm_access = NULL;
 
1355
 
 
1356
        svn_error_t *error = svn_wc_adm_probe_open( &adm_access, NULL, norm_path.c_str(), false, false, pool );
 
1357
        if( error != NULL )
 
1358
            throw SvnException( error );
 
1359
 
 
1360
        const svn_wc_entry_t *entry = NULL;
 
1361
        error = svn_wc_entry( &entry, norm_path.c_str(), adm_access, false, pool );
 
1362
        if( error != NULL )
 
1363
            throw SvnException( error );
 
1364
 
 
1365
        if( entry == NULL )
 
1366
            return Py::Nothing();
 
1367
 
 
1368
        return Py::asObject( new pysvn_entry( entry, m_context ) );
 
1369
    }
 
1370
    catch( SvnException &e )
 
1371
    {
 
1372
        // use callback error over ClientException
 
1373
        m_context.checkForError( m_module.client_error );
 
1374
 
 
1375
        throw_client_error( e );
 
1376
        return Py::Nothing();       // needed to remove warning about return value missing
 
1377
    }
 
1378
}
 
1379
 
965
1380
#ifdef PYSVN_HAS_CLIENT_INFO
966
1381
class InfoReceiveBaton
967
1382
{
1013
1428
 
1014
1429
    std::string path( args.getUtf8String( name_url_or_path ) );
1015
1430
 
1016
 
    svn_opt_revision_t revision = args.getRevision( name_revision, svn_opt_revision_unspecified );
1017
 
    svn_opt_revision_t peg_revision = args.getRevision( name_peg_revision, svn_opt_revision_unspecified );
 
1431
    svn_opt_revision_kind kind = svn_opt_revision_unspecified;
 
1432
    if( is_svn_url( path ) )
 
1433
        kind = svn_opt_revision_head;
 
1434
 
 
1435
    svn_opt_revision_t revision = args.getRevision( name_revision, kind );
 
1436
    svn_opt_revision_t peg_revision = args.getRevision( name_peg_revision, revision );
1018
1437
 
1019
1438
    bool recurse = args.getBoolean( name_recurse, true );
1020
1439
 
1058
1477
}
1059
1478
#endif
1060
1479
 
1061
 
Py::Object pysvn_client::cmd_info( const Py::Tuple &a_args, const Py::Dict &a_kws )
1062
 
{
1063
 
    static argument_description args_desc[] =
1064
 
    {
1065
 
    { true,  name_path },
1066
 
    { false, NULL }
1067
 
    };
1068
 
    FunctionArguments args( "info", args_desc, a_args, a_kws );
1069
 
    args.check();
1070
 
 
1071
 
    std::string path( args.getUtf8String( name_path ) );
1072
 
 
1073
 
    SvnPool pool( m_context );
1074
 
    try
1075
 
    {
1076
 
        std::string norm_path( svnNormalisedIfPath( path, pool ) );
1077
 
 
1078
 
        checkThreadPermission();
1079
 
 
1080
 
        PythonAllowThreads permission( m_context );
1081
 
 
1082
 
        svn_wc_adm_access_t *adm_access = NULL;
1083
 
 
1084
 
        svn_error_t *error = svn_wc_adm_probe_open( &adm_access, NULL, norm_path.c_str(), false, false, pool );
1085
 
        if( error != NULL )
1086
 
            throw SvnException( error );
1087
 
 
1088
 
        const svn_wc_entry_t *entry = NULL;
1089
 
        error = svn_wc_entry( &entry, norm_path.c_str(), adm_access, false, pool );
1090
 
        if( error != NULL )
1091
 
            throw SvnException( error );
1092
 
 
1093
 
        if( entry == NULL )
1094
 
            return Py::Nothing();
1095
 
 
1096
 
        return Py::asObject( new pysvn_entry( entry, m_context ) );
1097
 
    }
1098
 
    catch( SvnException &e )
1099
 
    {
1100
 
        // use callback error over ClientException
1101
 
        m_context.checkForError( m_module.client_error );
1102
 
 
1103
 
        throw_client_error( e );
1104
 
        return Py::Nothing();       // needed to remove warning about return value missing
1105
 
    }
1106
 
}
1107
 
 
1108
 
Py::Object pysvn_client::cmd_import( const Py::Tuple &a_args, const Py::Dict &a_kws )
1109
 
{
1110
 
    static argument_description args_desc[] =
1111
 
    {
1112
 
    { true,  name_path },
1113
 
    { true,  name_url },
1114
 
    { true,  name_log_message },
1115
 
    { false, name_recurse },
1116
 
    { false, NULL }
1117
 
    };
1118
 
    FunctionArguments args( "import_", args_desc, a_args, a_kws );
1119
 
    args.check();
1120
 
 
1121
 
    std::string path( args.getUtf8String( name_path ) );
1122
 
    std::string url( args.getUtf8String( name_url ) );
1123
 
    std::string message( args.getUtf8String( name_log_message ) );
1124
 
 
1125
 
    bool recurse = args.getBoolean( name_recurse, true );
1126
 
 
1127
 
    SvnPool pool( m_context );
1128
 
    svn_client_commit_info_t *commit_info = NULL;
1129
 
 
1130
 
    try
1131
 
    {
1132
 
        std::string norm_path( svnNormalisedIfPath( path, pool ) );
1133
 
 
1134
 
        checkThreadPermission();
1135
 
 
1136
 
        PythonAllowThreads permission( m_context );
1137
 
 
1138
 
        m_context.setLogMessage( message.c_str() );
1139
 
 
1140
 
        svn_error_t *error = svn_client_import
1141
 
            (
1142
 
            &commit_info,
1143
 
            norm_path.c_str(),
1144
 
            url.c_str(),
1145
 
            !recurse,        // non_recursive
1146
 
            m_context,
1147
 
            pool
1148
 
            );
1149
 
 
1150
 
        if( error != NULL )
1151
 
            throw SvnException( error );
1152
 
    }
1153
 
    catch( SvnException &e )
1154
 
    {
1155
 
        // use callback error over ClientException
1156
 
        m_context.checkForError( m_module.client_error );
1157
 
 
1158
 
        throw_client_error( e );
1159
 
    }
1160
 
 
1161
 
    return toObject( commit_info );
1162
 
}
1163
 
 
1164
 
 
1165
1480
class LogChangePathInfo
1166
1481
{
1167
1482
public:
1340
1655
    { false, name_revision_end },
1341
1656
    { false, name_discover_changed_paths },
1342
1657
    { false, name_strict_node_history },
 
1658
#ifdef PYSVN_HAS_CLIENT_LOG2
 
1659
    { false, name_limit },
 
1660
#endif
1343
1661
    { false, NULL }
1344
1662
    };
1345
1663
    FunctionArguments args( "log", args_desc, a_args, a_kws );
1349
1667
    svn_opt_revision_t revision_end = args.getRevision( name_revision_end, svn_opt_revision_number );
1350
1668
    bool discover_changed_paths = args.getBoolean( name_discover_changed_paths, false );
1351
1669
    bool strict_node_history = args.getBoolean( name_strict_node_history, true );
1352
 
 
 
1670
    int limit = args.getInteger( name_limit, 0 );
1353
1671
    SvnPool pool( m_context );
1354
1672
    std::list<LogEntryInfo> all_entries;
1355
1673
 
1361
1679
 
1362
1680
        PythonAllowThreads permission( m_context );
1363
1681
 
 
1682
#ifdef PYSVN_HAS_CLIENT_LOG2
 
1683
        svn_error_t *error = svn_client_log2
 
1684
            (
 
1685
            targets,
 
1686
            &revision_start,
 
1687
            &revision_end,
 
1688
            limit,
 
1689
            discover_changed_paths,
 
1690
            strict_node_history,
 
1691
            logReceiver,
 
1692
            &all_entries,
 
1693
            m_context,
 
1694
            pool
 
1695
            );
 
1696
#else
1364
1697
        svn_error_t *error = svn_client_log
1365
1698
            (
1366
1699
            targets,
1373
1706
            m_context,
1374
1707
            pool
1375
1708
            );
1376
 
 
 
1709
#endif
1377
1710
        if( error != NULL )
1378
1711
            throw SvnException( error );
1379
1712
    }
1442
1775
    { true,  name_url_or_path },
1443
1776
    { false, name_revision },
1444
1777
    { false, name_recurse },
 
1778
#ifdef PYSVN_HAS_CLIENT_LS2
 
1779
    { false, name_peg_revision },
 
1780
#endif
1445
1781
    { false, NULL }
1446
1782
    };
1447
1783
    FunctionArguments args( "ls", args_desc, a_args, a_kws );
1454
1790
    SvnPool pool( m_context );
1455
1791
    apr_hash_t *hash = NULL;
1456
1792
    std::string norm_path( svnNormalisedIfPath( path, pool ) );
 
1793
#ifdef PYSVN_HAS_CLIENT_LS2
 
1794
    svn_opt_revision_t peg_revision = args.getRevision( name_peg_revision, revision );
 
1795
#endif
1457
1796
 
1458
1797
    try
1459
1798
    {
1461
1800
 
1462
1801
        PythonAllowThreads permission( m_context );
1463
1802
 
 
1803
#ifdef PYSVN_HAS_CLIENT_LS2
 
1804
        svn_error_t *error = svn_client_ls2
 
1805
            (
 
1806
            &hash,
 
1807
            norm_path.c_str(),
 
1808
            &peg_revision,
 
1809
            &revision,
 
1810
            recurse,
 
1811
            m_context,
 
1812
            pool
 
1813
            );
 
1814
#else
1464
1815
        svn_error_t *error = svn_client_ls
1465
1816
            (
1466
1817
            &hash,
1470
1821
            m_context,
1471
1822
            pool
1472
1823
            );
 
1824
#endif
1473
1825
 
1474
1826
        if( error != 0 )
1475
1827
            throw SvnException( error );
1546
1898
    bool force = args.getBoolean( name_force, false );
1547
1899
    bool recurse = args.getBoolean( name_recurse, true );
1548
1900
    bool notice_ancestry = args.getBoolean( name_notice_ancestry, false );
1549
 
    bool dry_run = args.getBoolean( name_dry_run, true );
 
1901
    bool dry_run = args.getBoolean( name_dry_run, false );
1550
1902
 
1551
1903
    SvnPool pool( m_context );
1552
1904
 
1562
1914
 
1563
1915
        svn_error_t *error = svn_client_merge
1564
1916
            (
1565
 
            norm_path1.c_str (),
1566
 
            &revision1,
1567
 
            norm_path2.c_str (),
1568
 
            &revision2,
1569
 
            norm_local_path.c_str (),
1570
 
            recurse,
1571
 
            !notice_ancestry,
1572
 
            force,
1573
 
            dry_run,
1574
 
            m_context,
1575
 
            pool
1576
 
            );
1577
 
        if( error != 0 )
1578
 
            throw SvnException( error );
1579
 
    }
1580
 
    catch( SvnException &e )
1581
 
    {
1582
 
        // use callback error over ClientException
1583
 
        m_context.checkForError( m_module.client_error );
1584
 
 
1585
 
        throw_client_error( e );
1586
 
    }
1587
 
 
1588
 
    return Py::Nothing();
1589
 
}
 
1917
            norm_path1.c_str(),
 
1918
            &revision1,
 
1919
            norm_path2.c_str(),
 
1920
            &revision2,
 
1921
            norm_local_path.c_str(),
 
1922
            recurse,
 
1923
            !notice_ancestry,
 
1924
            force,
 
1925
            dry_run,
 
1926
            m_context,
 
1927
            pool
 
1928
            );
 
1929
        if( error != 0 )
 
1930
            throw SvnException( error );
 
1931
    }
 
1932
    catch( SvnException &e )
 
1933
    {
 
1934
        // use callback error over ClientException
 
1935
        m_context.checkForError( m_module.client_error );
 
1936
 
 
1937
        throw_client_error( e );
 
1938
    }
 
1939
 
 
1940
    return Py::Nothing();
 
1941
}
 
1942
 
 
1943
#ifdef PYSVN_HAS_CLIENT_MERGE_PEG
 
1944
Py::Object pysvn_client::cmd_merge_peg( const Py::Tuple &a_args, const Py::Dict &a_kws )
 
1945
{
 
1946
    static argument_description args_desc[] =
 
1947
    {
 
1948
    { true,  name_url_or_path },
 
1949
    { true,  name_revision1 },
 
1950
    { true,  name_revision2 },
 
1951
    { true,  name_peg_revision },
 
1952
    { true,  name_local_path },
 
1953
    { false, name_recurse },
 
1954
    { false, name_notice_ancestry },
 
1955
    { false, name_force },
 
1956
    { false, name_dry_run },
 
1957
    { false, NULL }
 
1958
    };
 
1959
    FunctionArguments args( "merge", args_desc, a_args, a_kws );
 
1960
    args.check();
 
1961
 
 
1962
    std::string path( args.getUtf8String( name_url_or_path ) );
 
1963
    svn_opt_revision_t revision1 = args.getRevision( name_revision1, svn_opt_revision_head );
 
1964
    svn_opt_revision_t revision2 = args.getRevision( name_revision2, svn_opt_revision_head );
 
1965
    svn_opt_revision_t peg_revision = args.getRevision( name_revision2, revision2 );
 
1966
    std::string local_path( args.getUtf8String( name_local_path ) );
 
1967
 
 
1968
    bool force = args.getBoolean( name_force, false );
 
1969
    bool recurse = args.getBoolean( name_recurse, true );
 
1970
    bool notice_ancestry = args.getBoolean( name_notice_ancestry, false );
 
1971
    bool dry_run = args.getBoolean( name_dry_run, false );
 
1972
 
 
1973
    SvnPool pool( m_context );
 
1974
 
 
1975
    try
 
1976
    {
 
1977
        std::string norm_path( svnNormalisedIfPath( path, pool ) );
 
1978
        std::string norm_local_path( svnNormalisedIfPath( local_path, pool ) );
 
1979
 
 
1980
        checkThreadPermission();
 
1981
 
 
1982
        PythonAllowThreads permission( m_context );
 
1983
 
 
1984
        svn_error_t *error = svn_client_merge_peg
 
1985
            (
 
1986
            norm_path.c_str(),
 
1987
            &revision1,
 
1988
            &revision2,
 
1989
            &peg_revision,
 
1990
            norm_local_path.c_str(),
 
1991
            recurse,
 
1992
            !notice_ancestry,
 
1993
            force,
 
1994
            dry_run,
 
1995
            m_context,
 
1996
            pool
 
1997
            );
 
1998
        if( error != 0 )
 
1999
            throw SvnException( error );
 
2000
    }
 
2001
    catch( SvnException &e )
 
2002
    {
 
2003
        // use callback error over ClientException
 
2004
        m_context.checkForError( m_module.client_error );
 
2005
 
 
2006
        throw_client_error( e );
 
2007
    }
 
2008
 
 
2009
    return Py::Nothing();
 
2010
}
 
2011
#endif
1590
2012
 
1591
2013
Py::Object pysvn_client::cmd_mkdir( const Py::Tuple &a_args, const Py::Dict &a_kws )
1592
2014
{
1620
2042
        throw Py::TypeError( type_error_message );
1621
2043
    }
1622
2044
 
1623
 
    svn_client_commit_info_t *commit_info = NULL;
 
2045
    pysvn_commit_info_t *commit_info = NULL;
1624
2046
 
1625
2047
    try
1626
2048
    {
1630
2052
 
1631
2053
        m_context.setLogMessage( message.c_str() );
1632
2054
 
 
2055
 
 
2056
#if defined( PYSVN_HAS_CLIENT_MKDIR2 )
 
2057
        svn_error_t *error = svn_client_mkdir2
 
2058
            (
 
2059
            &commit_info,       // changed type
 
2060
            targets,
 
2061
            m_context,
 
2062
            pool
 
2063
            );
 
2064
#else
1633
2065
        svn_error_t *error = svn_client_mkdir
1634
2066
            (
1635
2067
            &commit_info,
1637
2069
            m_context,
1638
2070
            pool
1639
2071
            );
1640
 
 
 
2072
#endif
1641
2073
        if( error != 0 )
1642
2074
            throw SvnException( error );
1643
2075
    }
1658
2090
    {
1659
2091
    { true,  name_src_url_or_path },
1660
2092
    { true,  name_dest_url_or_path },
1661
 
    { false, name_src_revision },
1662
2093
    { false, name_force },
1663
2094
    { false, NULL }
1664
2095
    };
1666
2097
    args.check();
1667
2098
 
1668
2099
    SvnPool pool( m_context );
1669
 
    svn_client_commit_info_t *commit_info = NULL;
 
2100
    pysvn_commit_info_t *commit_info = NULL;
1670
2101
 
1671
2102
    std::string type_error_message;
1672
2103
    try
1677
2108
        type_error_message = "expecting string for dest_url_or_path (arg 2)";
1678
2109
        Py::String dest_path( args.getUtf8String( name_dest_url_or_path ) );
1679
2110
 
1680
 
        type_error_message = "expecting revision for keyword src_revision";
1681
 
        svn_opt_revision_t revision = args.getRevision( name_src_revision, svn_opt_revision_head );
 
2111
#ifndef PYSVN_HAS_CLIENT_MOVE2
 
2112
        svn_opt_revision_t revision;
 
2113
        revision.kind = svn_opt_revision_head;
 
2114
#endif
1682
2115
 
1683
2116
        type_error_message = "expecting boolean for keyword force";
1684
2117
        bool force = args.getBoolean( name_force, false );
1692
2125
 
1693
2126
            PythonAllowThreads permission( m_context );
1694
2127
 
 
2128
#if defined( PYSVN_HAS_CLIENT_MOVE3 )
 
2129
            svn_error_t *error = svn_client_move3
 
2130
                (
 
2131
                &commit_info,               // changed type
 
2132
                norm_src_path.c_str(),
 
2133
                norm_dest_path.c_str(),
 
2134
                force,
 
2135
                m_context,
 
2136
                pool
 
2137
                );
 
2138
#elif defined( PYSVN_HAS_CLIENT_MOVE2 )
 
2139
            svn_error_t *error = svn_client_move2
 
2140
                (
 
2141
                &commit_info,
 
2142
                norm_src_path.c_str(),
 
2143
                norm_dest_path.c_str(),
 
2144
                force,
 
2145
                m_context,
 
2146
                pool
 
2147
                );
 
2148
#else
1695
2149
            svn_error_t *error = svn_client_move
1696
2150
                (
1697
2151
                &commit_info,
1702
2156
                m_context,
1703
2157
                pool
1704
2158
                );
 
2159
#endif
1705
2160
 
1706
2161
            if( error != NULL )
1707
2162
                throw SvnException( error );
1730
2185
    { true,  name_url_or_path },
1731
2186
    { false, name_revision },
1732
2187
    { false, name_recurse },
 
2188
#ifdef PYSVN_HAS_CLIENT_PROPSET2
 
2189
    { false, name_skip_checks },
 
2190
#endif
1733
2191
    { false, NULL }
1734
2192
    };
1735
2193
    FunctionArguments args( "propdel", args_desc, a_args, a_kws );
1745
2203
        revision = args.getRevision( name_revision, svn_opt_revision_working );
1746
2204
 
1747
2205
    bool recurse = args.getBoolean( name_recurse, false );
 
2206
#ifdef PYSVN_HAS_CLIENT_PROPSET2
 
2207
    bool skip_checks = args.getBoolean( name_skip_checks, false );
 
2208
#endif
1748
2209
 
1749
2210
    SvnPool pool( m_context );
1750
2211
    try
1754
2215
        checkThreadPermission();
1755
2216
 
1756
2217
        PythonAllowThreads permission( m_context );
 
2218
 
 
2219
#ifdef PYSVN_HAS_CLIENT_PROPSET2
 
2220
        svn_error_t *error = svn_client_propset2
 
2221
            (
 
2222
            propname.c_str(),
 
2223
            NULL, // value = NULL
 
2224
            norm_path.c_str(),
 
2225
            recurse,
 
2226
            skip_checks,
 
2227
            m_context.ctx(),
 
2228
            pool
 
2229
            );
 
2230
#else
1757
2231
        svn_error_t *error = svn_client_propset
1758
2232
            (
1759
2233
            propname.c_str(),
1760
2234
            NULL, // value = NULL
1761
 
            norm_path.c_str (),
 
2235
            norm_path.c_str(),
1762
2236
            recurse,
1763
2237
            pool
1764
2238
            );
 
2239
#endif
1765
2240
        if( error != NULL )
1766
2241
            throw SvnException( error );
1767
2242
    }
1784
2259
    { true,  name_url_or_path },
1785
2260
    { false, name_revision },
1786
2261
    { false, name_recurse },
 
2262
#ifdef PYSVN_HAS_CLIENT_PROPGET2
 
2263
    { false, name_peg_revision },
 
2264
#endif
1787
2265
    { false, NULL }
1788
2266
    };
1789
2267
    FunctionArguments args( "propget", args_desc, a_args, a_kws );
1798
2276
        revision = args.getRevision( name_revision, svn_opt_revision_head );
1799
2277
    else
1800
2278
        revision = args.getRevision( name_revision, svn_opt_revision_working );
 
2279
#ifdef PYSVN_HAS_CLIENT_PROPGET2
 
2280
    svn_opt_revision_t peg_revision = args.getRevision( name_peg_revision, revision );
 
2281
#endif
1801
2282
 
1802
2283
    SvnPool pool( m_context );
1803
2284
    apr_hash_t *props = NULL;
1809
2290
        checkThreadPermission();
1810
2291
 
1811
2292
        PythonAllowThreads permission( m_context );
 
2293
#ifdef PYSVN_HAS_CLIENT_PROPGET2
 
2294
        svn_error_t *error = svn_client_propget2
 
2295
            (
 
2296
            &props,
 
2297
            propname.c_str(),
 
2298
            norm_path.c_str(),
 
2299
            &peg_revision,
 
2300
            &revision,
 
2301
            recurse,
 
2302
            m_context,
 
2303
            pool
 
2304
            );
 
2305
#else
1812
2306
        svn_error_t *error = svn_client_propget
1813
2307
            (
1814
2308
            &props,
1819
2313
            m_context,
1820
2314
            pool
1821
2315
            );
 
2316
#endif
1822
2317
        if( error != NULL )
1823
2318
            throw SvnException( error );
1824
2319
    }
1840
2335
    { true,  name_url_or_path },
1841
2336
    { false, name_revision },
1842
2337
    { false, name_recurse },
 
2338
#ifdef PYSVN_HAS_CLIENT_PROPLIST2
 
2339
    { false, name_peg_revision },
 
2340
#endif
1843
2341
    { false, NULL }
1844
2342
    };
1845
2343
    FunctionArguments args( "proplist", args_desc, a_args, a_kws );
1848
2346
    Py::List path_list( toListOfStrings( args.getArg( name_url_or_path ) ) );
1849
2347
 
1850
2348
    bool recurse = args.getBoolean( name_recurse, false );
1851
 
    svn_opt_revision_t revision;
1852
2349
 
1853
2350
    bool is_revision_setup = false;
1854
2351
    bool is_url = false;
1865
2362
        revision_url.kind = svn_opt_revision_head;
1866
2363
        revision_file.kind = svn_opt_revision_working;
1867
2364
    }
 
2365
#ifdef PYSVN_HAS_CLIENT_PROPLIST2
 
2366
    svn_opt_revision_t peg_revision_url;
 
2367
    svn_opt_revision_t peg_revision_file;
 
2368
    if( args.hasArg( name_peg_revision ) )
 
2369
    {
 
2370
        peg_revision_url = args.getRevision( name_peg_revision );
 
2371
        peg_revision_file = peg_revision_url;
 
2372
    }
 
2373
    else
 
2374
    {
 
2375
        peg_revision_url = revision_url;
 
2376
        peg_revision_file = revision_file;
 
2377
    }
 
2378
#endif
1868
2379
 
1869
2380
    SvnPool pool( m_context );
1870
2381
 
1876
2387
        std::string path( path_str.as_std_string() );
1877
2388
        std::string norm_path( svnNormalisedIfPath( path, pool ) );
1878
2389
 
 
2390
        svn_opt_revision_t revision;
 
2391
        svn_opt_revision_t peg_revision;
1879
2392
        if( !is_revision_setup )
1880
2393
            if( is_svn_url( path ) )
1881
2394
            {
1882
2395
                revision = revision_url;
 
2396
                peg_revision = peg_revision_url;
1883
2397
                is_url = true;
1884
2398
            }
1885
2399
            else
1886
2400
            {
1887
2401
                revision = revision_file;
 
2402
                peg_revision = peg_revision_file;
1888
2403
            }
1889
2404
        else
1890
2405
            if( is_svn_url( path ) && !is_url )
1895
2410
        apr_array_header_t *props = NULL;
1896
2411
        try
1897
2412
        {
1898
 
            const char *norm_path_c_str = norm_path.c_str();
 
2413
            const char *norm_path_c_str= norm_path.c_str();
1899
2414
            checkThreadPermission();
1900
2415
 
1901
2416
            PythonAllowThreads permission( m_context );
 
2417
#ifdef PYSVN_HAS_CLIENT_PROPLIST2
 
2418
            svn_error_t *error = svn_client_proplist2
 
2419
                (
 
2420
                &props,
 
2421
                norm_path_c_str,
 
2422
                &peg_revision,
 
2423
                &revision,
 
2424
                recurse,
 
2425
                m_context,
 
2426
                pool
 
2427
                );
 
2428
#else
1902
2429
            svn_error_t *error = svn_client_proplist
1903
2430
                (
1904
2431
                &props,
1908
2435
                m_context,
1909
2436
                pool
1910
2437
                );
 
2438
#endif
1911
2439
            if( error != NULL )
1912
2440
                throw SvnException( error );
1913
2441
        }
1934
2462
    { true,  name_url_or_path },
1935
2463
    { false, name_revision },
1936
2464
    { false, name_recurse },
 
2465
#ifdef PYSVN_HAS_CLIENT_PROPSET2
 
2466
    { false, name_skip_checks },
 
2467
#endif
1937
2468
    { false, NULL }
1938
2469
    };
1939
2470
    FunctionArguments args( "propset", args_desc, a_args, a_kws );
1950
2481
        revision = args.getRevision( name_revision, svn_opt_revision_working );
1951
2482
 
1952
2483
    bool recurse = args.getBoolean( name_recurse, false );
 
2484
#ifdef PYSVN_HAS_CLIENT_PROPSET2
 
2485
    bool skip_checks = args.getBoolean( name_skip_checks, false );
 
2486
#endif
1953
2487
 
1954
2488
    SvnPool pool( m_context );
1955
2489
 
1963
2497
 
1964
2498
        const svn_string_t *svn_propval = svn_string_ncreate( propval.c_str(), propval.size(), pool );
1965
2499
 
 
2500
#ifdef PYSVN_HAS_CLIENT_PROPSET2
 
2501
        svn_error_t *error = svn_client_propset2
 
2502
            (
 
2503
            propname.c_str(),
 
2504
            svn_propval,
 
2505
            norm_path.c_str(),
 
2506
            recurse,
 
2507
            skip_checks,
 
2508
            m_context.ctx(),
 
2509
            pool
 
2510
            );
 
2511
#else
1966
2512
        svn_error_t *error = svn_client_propset
1967
2513
            (
1968
2514
            propname.c_str(),
1971
2517
            recurse,
1972
2518
            pool
1973
2519
            );
 
2520
#endif
1974
2521
        if( error != NULL )
1975
2522
            throw SvnException( error );
1976
2523
    }
2052
2599
    SvnPool pool( m_context );
2053
2600
    apr_array_header_t *targets = targetsFromStringOrList( args.getArg( name_url_or_path ), pool );
2054
2601
 
2055
 
    svn_client_commit_info_t *commit_info = NULL;
 
2602
    pysvn_commit_info_t *commit_info = NULL;
2056
2603
    try
2057
2604
    {
2058
2605
        checkThreadPermission();
2059
2606
 
2060
2607
        PythonAllowThreads permission( m_context );
2061
2608
 
 
2609
#if defined( PYSVN_HAS_CLIENT_DELETE2 )
 
2610
        svn_error_t *error = svn_client_delete2
 
2611
            (
 
2612
            &commit_info,       // commit_info changed
 
2613
            targets,
 
2614
            force,
 
2615
            m_context,
 
2616
            pool
 
2617
            );
 
2618
#else
2062
2619
        svn_error_t *error = svn_client_delete
2063
2620
            (
2064
2621
            &commit_info,
2067
2624
            m_context,
2068
2625
            pool
2069
2626
            );
 
2627
#endif
2070
2628
        if( error != NULL )
2071
2629
            throw SvnException( error );
2072
2630
    }
2664
3222
}
2665
3223
#endif
2666
3224
 
 
3225
#ifdef PYSVN_HAS_CLIENT_UPDATE2
 
3226
Py::Object pysvn_client::cmd_update( const Py::Tuple &a_args, const Py::Dict &a_kws )
 
3227
{
 
3228
    static argument_description args_desc[] =
 
3229
    {
 
3230
    { true,  name_path },
 
3231
    { false, name_recurse },
 
3232
    { false, name_revision },
 
3233
#ifdef PYSVN_HAS_CLIENT_UPDATE2
 
3234
    { false, name_ignore_externals },
 
3235
#endif
 
3236
    { false, NULL }
 
3237
    };
 
3238
    FunctionArguments args( "update", args_desc, a_args, a_kws );
 
3239
    args.check();
 
3240
 
 
3241
    SvnPool pool( m_context );
 
3242
 
 
3243
    apr_array_header_t *targets = targetsFromStringOrList( args.getArg( name_path ), pool );
 
3244
 
 
3245
    svn_opt_revision_t revision = args.getRevision( name_revision, svn_opt_revision_head );
 
3246
    bool recurse = args.getBoolean( name_recurse, true );
 
3247
#ifdef PYSVN_HAS_CLIENT_UPDATE2
 
3248
    bool ignore_externals = args.getBoolean( name_recurse, false );
 
3249
#endif
 
3250
    apr_array_header_t *result_revs = NULL;
 
3251
 
 
3252
    try
 
3253
    {
 
3254
        checkThreadPermission();
 
3255
 
 
3256
        PythonAllowThreads permission( m_context );
 
3257
 
 
3258
#ifdef PYSVN_HAS_CLIENT_UPDATE2
 
3259
        svn_error_t *error = svn_client_update2
 
3260
            (
 
3261
            &result_revs,
 
3262
            targets,
 
3263
            &revision,
 
3264
            recurse,
 
3265
            ignore_externals,
 
3266
            m_context,
 
3267
            pool
 
3268
            );
 
3269
#else
 
3270
        svn_error_t *error = svn_client_update
 
3271
            (
 
3272
            &result_revs,
 
3273
            targets,
 
3274
            &revision,
 
3275
            recurse,
 
3276
            m_context,
 
3277
            pool
 
3278
            );
 
3279
#endif
 
3280
        if( error != NULL )
 
3281
            throw SvnException( error );
 
3282
    }
 
3283
    catch( SvnException &e )
 
3284
    {
 
3285
        // use callback error over ClientException
 
3286
        m_context.checkForError( m_module.client_error );
 
3287
 
 
3288
        throw_client_error( e );
 
3289
    }
 
3290
 
 
3291
    return revnumListToObject( result_revs, pool );
 
3292
}
 
3293
 
 
3294
#else
2667
3295
Py::Object pysvn_client::cmd_update( const Py::Tuple &a_args, const Py::Dict &a_kws )
2668
3296
{
2669
3297
    static argument_description args_desc[] =
2694
3322
        svn_error_t *error = svn_client_update
2695
3323
            (
2696
3324
            &revnum,
2697
 
            norm_path.c_str (),
 
3325
            norm_path.c_str(),
2698
3326
            &revision,
2699
3327
            recurse,
2700
3328
            m_context,
2701
3329
            pool
2702
3330
            );
 
3331
 
2703
3332
        if( error != NULL )
2704
3333
            throw SvnException( error );
2705
3334
    }
2713
3342
 
2714
3343
    return Py::asObject( new pysvn_revision( svn_opt_revision_number, 0, revnum ) );
2715
3344
}
 
3345
#endif
2716
3346
 
2717
3347
Py::Object pysvn_client::get_auth_cache( const Py::Tuple &a_args, const Py::Dict &a_kws )
2718
3348
{
2896
3526
void pysvn_client::init_type()
2897
3527
{
2898
3528
    behaviors().name("Client");
2899
 
    behaviors().doc( class_client_doc );
 
3529
    behaviors().doc( pysvn_client_doc );
2900
3530
    behaviors().supportGetattr();
2901
3531
    behaviors().supportSetattr();
2902
3532
 
2903
 
    add_keyword_method("add", &pysvn_client::cmd_add, PYSVN_ADD_DOC );
2904
 
    add_keyword_method("annotate", &pysvn_client::cmd_annotate, PYSVN_ANNOTATE_DOC );
2905
 
    add_keyword_method("cat", &pysvn_client::cmd_cat, PYSVN_CAT_DOC );
2906
 
    add_keyword_method("checkin", &pysvn_client::cmd_checkin, PYSVN_CHECKIN_DOC );
2907
 
    add_keyword_method("checkout", &pysvn_client::cmd_checkout, PYSVN_CHECKOUT_DOC );
2908
 
    add_keyword_method("cleanup", &pysvn_client::cmd_cleanup, PYSVN_CLEANUP_DOC );
2909
 
    add_keyword_method("copy", &pysvn_client::cmd_copy, PYSVN_COPY_DOC );
2910
 
    add_keyword_method("diff", &pysvn_client::cmd_diff, PYSVN_DIFF_DOC );
2911
 
    add_keyword_method("export", &pysvn_client::cmd_export, PYSVN_EXPORT_DOC );
2912
 
    add_keyword_method("import_", &pysvn_client::cmd_import, PYSVN_IMPORT_DOC );
2913
 
    add_keyword_method("info", &pysvn_client::cmd_info, PYSVN_INFO_DOC );
 
3533
    add_keyword_method("add", &pysvn_client::cmd_add, pysvn_client_add_doc );
 
3534
    add_keyword_method("annotate", &pysvn_client::cmd_annotate, pysvn_client_annotate_doc );
 
3535
    add_keyword_method("cat", &pysvn_client::cmd_cat, pysvn_client_cat_doc );
 
3536
    add_keyword_method("checkin", &pysvn_client::cmd_checkin, pysvn_client_checkin_doc );
 
3537
    add_keyword_method("checkout", &pysvn_client::cmd_checkout, pysvn_client_checkout_doc );
 
3538
    add_keyword_method("cleanup", &pysvn_client::cmd_cleanup, pysvn_client_cleanup_doc );
 
3539
    add_keyword_method("copy", &pysvn_client::cmd_copy, pysvn_client_copy_doc );
 
3540
    add_keyword_method("diff", &pysvn_client::cmd_diff, pysvn_client_diff_doc );
 
3541
    add_keyword_method("export", &pysvn_client::cmd_export, pysvn_client_export_doc );
 
3542
    add_keyword_method("import_", &pysvn_client::cmd_import, pysvn_client_import__doc );
 
3543
    add_keyword_method("info", &pysvn_client::cmd_info, pysvn_client_info_doc );
2914
3544
 
2915
3545
#ifdef PYSVN_HAS_CLIENT_INFO
2916
 
    add_keyword_method("info2", &pysvn_client::cmd_info2, PYSVN_INFO2_DOC );
2917
 
#endif
2918
 
    add_keyword_method("is_url", &pysvn_client::is_url, IS_URL_DOC );
2919
 
#ifdef PYSVN_HAS_CLIENT_LOCK
2920
 
    add_keyword_method("lock", &pysvn_client::cmd_lock, PYSVN_LOCK_DOC );
2921
 
#endif
2922
 
    add_keyword_method("log", &pysvn_client::cmd_log, PYSVN_LOG_DOC );
2923
 
    add_keyword_method("ls", &pysvn_client::cmd_ls, PYSVN_LS_DOC );
2924
 
    add_keyword_method("merge", &pysvn_client::cmd_merge, PYSVN_MERGE_DOC );
2925
 
    add_keyword_method("mkdir", &pysvn_client::cmd_mkdir, PYSVN_MKDIR_DOC );
2926
 
    add_keyword_method("move", &pysvn_client::cmd_move, PYSVN_MOVE_DOC );
2927
 
    add_keyword_method("propdel", &pysvn_client::cmd_propdel, PYSVN_PROPDEL_DOC );
2928
 
    add_keyword_method("propget", &pysvn_client::cmd_propget, PYSVN_PROPGET_DOC );
2929
 
    add_keyword_method("proplist", &pysvn_client::cmd_proplist, PYSVN_PROPLIST_DOC );
2930
 
    add_keyword_method("propset", &pysvn_client::cmd_propset, PYSVN_PROPSET_DOC );
2931
 
    add_keyword_method("relocate", &pysvn_client::cmd_relocate, PYSVN_RELOCATE_DOC );
2932
 
    add_keyword_method("remove", &pysvn_client::cmd_remove, PYSVN_REMOVE_DOC );
2933
 
    add_keyword_method("resolved", &pysvn_client::cmd_resolved, PYSVN_RESOLVED_DOC );
2934
 
    add_keyword_method("revert", &pysvn_client::cmd_revert, PYSVN_REVERT_DOC );
2935
 
    add_keyword_method("revpropdel", &pysvn_client::cmd_revpropdel, PYSVN_REVPROPDEL_DOC );
2936
 
    add_keyword_method("revpropget", &pysvn_client::cmd_revpropget, PYSVN_REVPROPGET_DOC );
2937
 
    add_keyword_method("revproplist", &pysvn_client::cmd_revproplist, PYSVN_REVPROPLIST_DOC );
2938
 
    add_keyword_method("revpropset", &pysvn_client::cmd_revpropset, PYSVN_REVPROPSET_DOC );
2939
 
    add_keyword_method("get_auth_cache", &pysvn_client::get_auth_cache, GET_AUTH_CACHE_DOC );
2940
 
    add_keyword_method("set_auth_cache", &pysvn_client::set_auth_cache, SET_AUTH_CACHE_DOC );
2941
 
    add_keyword_method("get_auto_props", &pysvn_client::get_auto_props, GET_AUTO_PROPS_DOC );
2942
 
    add_keyword_method("set_auto_props", &pysvn_client::set_auto_props, SET_AUTO_PROPS_DOC );
2943
 
    add_keyword_method("status", &pysvn_client::cmd_status, PYSVN_STATUS_DOC );
2944
 
    add_keyword_method("switch", &pysvn_client::cmd_switch, PYSVN_SWITCH_DOC );
2945
 
#ifdef PYSVN_HAS_CLIENT_LOCK
2946
 
    add_keyword_method("unlock", &pysvn_client::cmd_unlock, PYSVN_UNLOCK_DOC );
2947
 
#endif
2948
 
    add_keyword_method("update", &pysvn_client::cmd_update, PYSVN_UPDATE_DOC );
 
3546
    add_keyword_method("info2", &pysvn_client::cmd_info2, pysvn_client_info2_doc );
 
3547
#endif
 
3548
    add_keyword_method("is_url", &pysvn_client::is_url, pysvn_client_is_url_doc );
 
3549
#ifdef PYSVN_HAS_CLIENT_LOCK
 
3550
    add_keyword_method("lock", &pysvn_client::cmd_lock, pysvn_client_lock_doc );
 
3551
#endif
 
3552
    add_keyword_method("log", &pysvn_client::cmd_log, pysvn_client_log_doc );
 
3553
    add_keyword_method("ls", &pysvn_client::cmd_ls, pysvn_client_ls_doc );
 
3554
    add_keyword_method("merge", &pysvn_client::cmd_merge, pysvn_client_merge_doc );
 
3555
    add_keyword_method("mkdir", &pysvn_client::cmd_mkdir, pysvn_client_mkdir_doc );
 
3556
    add_keyword_method("move", &pysvn_client::cmd_move, pysvn_client_move_doc );
 
3557
    add_keyword_method("propdel", &pysvn_client::cmd_propdel, pysvn_client_propdel_doc );
 
3558
    add_keyword_method("propget", &pysvn_client::cmd_propget, pysvn_client_propget_doc );
 
3559
    add_keyword_method("proplist", &pysvn_client::cmd_proplist, pysvn_client_proplist_doc );
 
3560
    add_keyword_method("propset", &pysvn_client::cmd_propset, pysvn_client_propset_doc );
 
3561
    add_keyword_method("relocate", &pysvn_client::cmd_relocate, pysvn_client_relocate_doc );
 
3562
    add_keyword_method("remove", &pysvn_client::cmd_remove, pysvn_client_remove_doc );
 
3563
    add_keyword_method("resolved", &pysvn_client::cmd_resolved, pysvn_client_resolved_doc );
 
3564
    add_keyword_method("revert", &pysvn_client::cmd_revert, pysvn_client_revert_doc );
 
3565
    add_keyword_method("revpropdel", &pysvn_client::cmd_revpropdel, pysvn_client_revpropdel_doc );
 
3566
    add_keyword_method("revpropget", &pysvn_client::cmd_revpropget, pysvn_client_revpropget_doc );
 
3567
    add_keyword_method("revproplist", &pysvn_client::cmd_revproplist, pysvn_client_revproplist_doc );
 
3568
    add_keyword_method("revpropset", &pysvn_client::cmd_revpropset, pysvn_client_revpropset_doc );
 
3569
    add_keyword_method("get_auth_cache", &pysvn_client::get_auth_cache, pysvn_client_get_auth_cache_doc );
 
3570
    add_keyword_method("set_auth_cache", &pysvn_client::set_auth_cache, pysvn_client_set_auth_cache_doc );
 
3571
    add_keyword_method("get_auto_props", &pysvn_client::get_auto_props, pysvn_client_get_auto_props_doc );
 
3572
    add_keyword_method("set_auto_props", &pysvn_client::set_auto_props, pysvn_client_set_auto_props_doc );
 
3573
    add_keyword_method("status", &pysvn_client::cmd_status, pysvn_client_status_doc );
 
3574
    add_keyword_method("switch", &pysvn_client::cmd_switch, pysvn_client_switch_doc );
 
3575
#ifdef PYSVN_HAS_CLIENT_LOCK
 
3576
    add_keyword_method("unlock", &pysvn_client::cmd_unlock, pysvn_client_unlock_doc );
 
3577
#endif
 
3578
    add_keyword_method("update", &pysvn_client::cmd_update, pysvn_client_update_doc );
2949
3579
}
2950
3580
 
2951
3581
//--------------------------------------------------------------------------------