Subversion Repositories DevTools

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
311 dpurdie 1
########################################################################
2
# Copyright (C) 1998-2008 ERG Limited, All rights reserved
3
#
4
# Module name   : jats_svn.pl
5
# Module type   : Jats Utility
6
# Compiler(s)   : Perl
7
# Environment(s): Jats
8
#
9
# Description   : A script to perform a number of SVN utility functions
10
#                 The script will:
11
#                   Delete a package
12
#                   Create a package
13
#                   Import source to a package
14
#
15
#
16
#......................................................................#
17
 
18
require 5.006_001;
19
use strict;
20
use warnings;
21
use JatsError;
22
use JatsSvn qw(:All);
23
use JatsLocateFiles;
379 dpurdie 24
use JatsProperties;
311 dpurdie 25
 
379 dpurdie 26
 
311 dpurdie 27
use Pod::Usage;                                 # required for help support
28
use Getopt::Long qw(:config require_order);     # Stop on non-option
29
use Cwd;
30
use File::Path;
31
use File::Copy;
32
use File::Basename;
33
use File::Compare;
387 dpurdie 34
use Encode;
311 dpurdie 35
 
36
my $VERSION = "1.0.0";                          # Update this
37
 
38
#
39
#   Options
40
#
41
my $opt_debug   = $ENV{'GBE_DEBUG'};            # Allow global debug
42
my $opt_verbose = $ENV{'GBE_VERBOSE'};          # Allow global verbose
43
my $opt_help = 0;
44
 
45
#
46
#   Globals
47
#
48
my $opr_done;                                   # User has done something
49
 
50
#-------------------------------------------------------------------------------
51
# Function        : Mainline Entry Point
52
#
53
# Description     :
54
#
55
# Inputs          :
56
#
57
my $result = GetOptions (
58
                "help:+"        => \$opt_help,              # flag, multiple use allowed
59
                "manual:3"      => \$opt_help,              # flag
60
                "verbose:+"     => \$opt_verbose,           # flag, multiple use allowed
61
 
62
                );
63
 
64
                #
65
                #   UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!
66
                #
67
 
68
#
69
#   Process help and manual options
70
#
71
pod2usage(-verbose => 0, -message => "Version: $VERSION") if ($opt_help == 1 || ! $result);
72
pod2usage(-verbose => 1) if ($opt_help == 2 );
73
pod2usage(-verbose => 2) if ($opt_help > 2);
74
 
75
#
76
#   Configure the error reporting process now that we have the user options
77
#
78
ErrorConfig( 'name'    =>'SVN',
79
             'verbose' => $opt_verbose,
80
            );
81
 
82
#
369 dpurdie 83
#   Reconfigure the options parser to allow subcommands to parse options
311 dpurdie 84
#
85
Getopt::Long::Configure('permute');
86
 
87
#
88
#   Process command
89
#   First command line argument is a subversion command
90
#
91
my $cmd = shift @ARGV || "help";
92
CreatePackage()                        if ( $cmd =~ m/^create/ );
385 dpurdie 93
DeleteBranch()                         if ( $cmd =~ m/^delete-branch/ );
311 dpurdie 94
DeletePackage()                        if ( $cmd =~ m/^delete-package/ );
95
ImportPackage()                        if ( $cmd =~ m/^import/ );
96
SvnRepoCmd($cmd, @ARGV)                if ( $cmd eq 'ls' );
363 dpurdie 97
TestSvn()                              if ($cmd eq 'test');
369 dpurdie 98
ShowPaths()                            if ( $cmd =~ m/^path/ );
99
ShowTag()                              if ( $cmd =~ m/^tag/ );
100
ShowUrl()                              if ( $cmd =~ m/^url/ );
311 dpurdie 101
 
102
pod2usage(-verbose => 0, -message => "No valid operations specified") unless ( $opr_done );
103
exit 0;
104
 
105
#-------------------------------------------------------------------------------
369 dpurdie 106
# Function        : ShowPaths
107
#
108
# Description     : Show PATHS
109
#
110
# Inputs          : 
111
#
112
# Returns         : 
113
#
114
sub ShowPaths
115
{
116
    #
117
    #   Parse more options
118
    #
119
    GetOptions (
120
                "help:+"        => \$opt_help,
121
                "manual:3"      => \$opt_help,
122
                ) || Error ("Invalid command line" );
123
 
124
    #
125
    #   Subcommand specific help
126
    #
127
    SubCommandHelp( $opt_help, "Subversion Paths") if ($opt_help || $#ARGV >= 0);
128
 
129
    #
130
    #   Display known PATHS
131
    #
132
    my ( $pSVN_URLS, $pSVN_URLS_LIST) = SvnPaths();
133
    print ("Configured SubVersion Repository Paths\n");
134
    print sprintf("    %-20s %s\n", 'Tag', 'URL Prefix');
135
 
136
    foreach my $key ( @{$pSVN_URLS_LIST} )
137
    {
138
        print sprintf("    %-20s %s\n", $key || 'Default', $pSVN_URLS->{$key} );
139
    }
140
 
141
    $opr_done = 1;
142
}
143
 
144
#-------------------------------------------------------------------------------
145
# Function        : ShowTag
146
#
147
# Description     : Convert a URL into a TAG
148
#                   Convert the current workspace info into a TAG
149
#
150
# Inputs          : url                     - Url to convert (optional)
151
#                   Options
152
#                       -help[=n]           - Show help
153
#                       -man                - Show manual
154
#                       -url=url            - Convert URL
155
#                       -path=path          - Convert Workspace
156
#
157
# Returns         : Nothing
158
#
159
sub ShowTag
160
{
161
    my $opt_path;
162
    my $opt_url;
163
 
164
    #
165
    #   Parse more options
166
    #
167
    GetOptions (
168
                "help:+"        => \$opt_help,
169
                "manual:3"      => \$opt_help,
170
                "path:s"        => \$opt_path,
171
                "url:s"         => \$opt_url,
172
                ) || Error ("Invalid command line" );
173
 
174
    #
175
    #   Subcommand specific help
176
    #
177
    SubCommandHelp( $opt_help, "Url to Tag") if ($opt_help);
178
 
179
    #
180
    #   Bare argument is a URL
181
    #   If no arguments provided assume a path of the current directory
182
    #
183
    $opt_url = shift (@ARGV) if ( $#ARGV == 0 );
184
    $opt_path = '.' unless ( defined $opt_path || defined $opt_url );
185
 
186
    #
187
    #   Sanity Tests
188
    #
189
    Error ("Cannot specify both a URL and a PATH")
190
            if ( defined $opt_url && defined $opt_path );
191
    Warning ("Too many arguments") if ( $#ARGV >= 0 );
192
 
193
    #   Do all the hard work
194
    #
195
    my $uref;
196
    if ( $opt_url )
197
    {
198
        $uref = NewSessionByUrl ( $opt_url );
199
        $uref->CalcRmReference($uref->Full());
200
    }
201
    else
202
    {
203
        $uref = NewSessionByWS($opt_path, 0, 1);
204
        my $ws_root = $uref->SvnLocateWsRoot(1);
205
        $uref->CalcRmReference($uref->FullWs());
206
    }
207
 
208
    Message ("Tag is: " . $uref->RmRef() );
209
    $opr_done = 1;
210
}
211
#-------------------------------------------------------------------------------
212
# Function        : ShowUrl
213
#
214
# Description     : Convert a TAG into a URL
215
#                   Show the current workspace URL
216
#
217
# Inputs          : tag                     - Tag to convert (optional)
218
#                   Options
219
#                       -help[=n]           - Show help
220
#                       -man                - Show manual
221
#                       -tag=tag            - Convert TAG
222
#                       -path=path          - Convert Workspace
223
#
224
# Returns         : Nothing
225
#
226
sub ShowUrl
227
{
228
    my $opt_path;
229
    my $opt_tag;
230
 
231
    #
232
    #   Parse more options
233
    #
234
    GetOptions (
235
                "help:+"        => \$opt_help,
236
                "manual:3"      => \$opt_help,
237
                "path:s"        => \$opt_path,
238
                "tag:s"         => \$opt_tag,
239
                ) || Error ("Invalid command line" );
240
 
241
    #
242
    #   Subcommand specific help
243
    #
244
    SubCommandHelp( $opt_help, "Tag to Url") if ($opt_help);
245
 
246
    #
247
    #   Bare argument is a TAG
248
    #   If no arguments provided assume a path of the current directory
249
    #
250
    $opt_tag = shift (@ARGV) if ( $#ARGV == 0 );
251
    $opt_path = '.' unless ( defined $opt_path || defined $opt_tag );
252
 
253
    #
254
    #   Sanity Tests
255
    #
256
    Error ("Cannot specify both a TAG and a PATH")
257
            if ( defined $opt_tag && defined $opt_path );
258
    Warning ("Too many arguments") if ( $#ARGV >= 0 );
259
 
260
    #   Do all the hard work
261
    #
262
    my $uref;
263
    my $url;
264
    if ( $opt_tag )
265
    {
266
        $url = SvnPath2Url($opt_tag);
267
    }
268
    else
269
    {
270
        $uref = NewSessionByWS($opt_path, 0, 1);
271
        my $ws_root = $uref->SvnLocateWsRoot(1);
272
        $url = $uref->FullWsRev();
273
    }
274
 
275
    Message ("Url: $url");
276
    $opr_done = 1;
277
}
278
 
279
#-------------------------------------------------------------------------------
363 dpurdie 280
# Function        : TestSvn
281
#
282
# Description     : Test access to subversion
283
#
284
# Inputs          : None
285
#
286
# Returns         :
287
#
288
sub TestSvn
289
{
290
    #
291
    #   Parse more options
292
    #
293
    GetOptions (
294
                "help:+"        => \$opt_help,
295
                "manual:3"      => \$opt_help,
296
                ) || Error ("Invalid command line" );
297
 
298
    #
299
    #   Subcommand specific help
300
    #
301
    SubCommandHelp( $opt_help, "Test Subversion") if ($opt_help || $#ARGV >= 0);
302
 
303
    SvnUserCmd( '--version');
304
    $opr_done = 1;
305
}
306
 
307
 
308
#-------------------------------------------------------------------------------
311 dpurdie 309
# Function        : SvnRepoCmd
310
#
311
# Description     : Execute a SVN command, where the first argument
312
#                   is a repository specifier
313
#
314
# Inputs          : $cmd
315
#                   $repo_url
316
#                   @opts
317
#
318
# Returns         : 
319
#
320
sub SvnRepoCmd
321
{
322
    my ( $cmd, $repo_url, @opts ) = @_;
323
    my $uref = NewSessionByUrl ( $repo_url );
324
 
325
    SvnUserCmd( $cmd,
326
            $uref->Full,
327
            @opts,
328
            { 'credentials' => 1 });
329
 
330
    $opr_done = 1;
331
}
332
 
333
#-------------------------------------------------------------------------------
334
# Function        : DeletePackage
335
#
336
# Description     : Delete a Package structure within a Repository
337
#                   Intended for test usage
338
#
339
# Inputs          : URL                 - Url to Repo + Package Base
340
#
341
# Returns         : 
342
#
343
sub DeletePackage
344
{
379 dpurdie 345
    my $opt_error = 0;
311 dpurdie 346
    #
347
    #   Parse more options
348
    #
349
    GetOptions (
350
                "help:+"        => \$opt_help,
351
                "manual:3"      => \$opt_help,
379 dpurdie 352
                "error!"       => \$opt_error,
311 dpurdie 353
                ) || Error ("Invalid command line" );
354
 
355
    #
356
    #   Subcommand specific help
357
    #
358
    SubCommandHelp( $opt_help, "Delete a Package") if ($opt_help || $#ARGV < 0);
359
 
360
    #
361
    #   Sanity Tests
362
    #
363
    Message ("Delete Entire Package Tree" );
364
    Warning ("Too many arguments: @ARGV") if ( $#ARGV >= 1 );
365
 
366
    #
367
    #   Do all the hard work
368
    #       Create
369
    #       Import
370
    #       Label
371
    #
372
    my $uref = NewSessionByUrl ( $ARGV[0] );
379 dpurdie 373
    $uref->SvnValidatePackageRoot(!$opt_error);
311 dpurdie 374
    $uref->SvnDelete (
375
                      'target'      => $uref->Full,
385 dpurdie 376
                      'comment'   => [$uref->Path().": Delete Package",'Deleted by user command: jats svn delete-package'],
379 dpurdie 377
                      'noerror'   => !$opt_error,
311 dpurdie 378
                      );
379
    $opr_done = 1;
380
}
381
 
382
#-------------------------------------------------------------------------------
383
# Function        : CreatePackage
384
#
385
# Description     : Create a Package structure within a Repository
386
#                   Optionally Import Data
387
#                   Optionally Tag the import
388
#                   Optionally Tag the import on a branch
389
#
390
# Inputs          : URL                 - Url to Repo + Package Base
391
#                   Options             - Command modifiers
392
#                       -import=path    - Import named directory
393
#                       -label=name     - Label the result
394
#                       -tag=name       - Import to Tag Only
395
#                       -branch=name    - Import to Branch only
396
#                       -new            - Must be new package
397
#                       -replace        - Replace existing
398
#
399
# Returns         : 
400
#
401
sub CreatePackage
402
{
403
    my $opt_import;
404
    my $opt_tag;
405
    my $opt_branch;
406
    my $opt_trunk;
407
    my $opt_new;
408
    my $opt_label;
409
    my $opt_replace;
410
    my $pname;
411
    my $type;
385 dpurdie 412
    my $opt_author;
413
    my $opt_date;
311 dpurdie 414
 
415
 
416
    Message ("Create New Package Version" );
417
 
418
    #
419
    #   Parse more options
420
    #
421
    GetOptions (
422
                "help:+"        => \$opt_help,
423
                "manual:3"      => \$opt_help,
424
                "verbose:+"     => \$opt_verbose,
425
                "import=s"      => \$opt_import,
426
                "new"           => \$opt_new,
427
                "branch=s"      => \$opt_branch,
428
                "trunk"         => \$opt_trunk,
429
                "tag=s"         => \$opt_tag,
430
                "label=s"       => \$opt_label,
431
                "replace"       => \$opt_replace,
385 dpurdie 432
                'author=s'      => \$opt_author,
433
                'date=s'        => \$opt_date,
311 dpurdie 434
 
435
                ) || Error ("Invalid command line" );
436
 
437
    #
438
    #   Subcommand specific help
439
    #
440
    SubCommandHelp( $opt_help, "Create a Package Version") if ($opt_help || $#ARGV < 0);
441
 
442
    #
369 dpurdie 443
    #   Alter the error reporting parameters
311 dpurdie 444
    #
445
    ErrorConfig( 'verbose' => $opt_verbose );
446
 
447
    #
448
    #   Sanity Tests
449
    #
450
    my $count = 0;
451
    $count++ if ( $opt_trunk );
452
    $count++ if ( $opt_branch );
453
    $count++ if ( $opt_tag );
454
    Error ("Conflicting options: -trunk, -tag, -branch") if ( $count > 1 );
455
    Error ("Nothing imported to be labeled") if ( $count && !$opt_import );
456
    Error ("Import path does not exist: $opt_import") if ( $opt_import && ! -d $opt_import );
457
    Error ("Conflicting options: new and replace") if ( $opt_new && $opt_replace );
385 dpurdie 458
    Error ("Too many command line arguments") if ( exists $ARGV[1] );
311 dpurdie 459
 
460
    ($type, $opt_label) = ('tags', $opt_tag)            if ( $opt_tag);
461
    ($type, $opt_label) = ('branches', $opt_branch)     if ( $opt_branch );
462
    ($type, $opt_label) = ('trunk', $opt_label)         if ( $opt_trunk);
463
 
464
    #
465
    #   Do all the hard work
466
    #       Create
467
    #       Import
468
    #       Label
469
    #
470
    my $uref = NewSessionByUrl ( $ARGV[0] );
471
    $uref->SvnCreatePackage (
472
                      'import'  => $opt_import,
473
                      'label'   => $opt_label,
474
                      'type'    => $type,
475
                      'new'     => $opt_new,
476
                      'replace' => $opt_replace,
477
                      );
385 dpurdie 478
    #
479
    # Report RmPath as using a pegged version of a new package is a bit silly
480
    #
481
    Message ("Repository Ref: " . $uref->RmPath);
482
    $uref->setRepoProperty('svn:author', $opt_author) if (defined ($opt_author));
483
    $uref->setRepoProperty('svn:date', $opt_date) if (defined ($opt_date));
311 dpurdie 484
    $opr_done = 1;
485
}
486
 
487
#-------------------------------------------------------------------------------
488
# Function        : ImportPackage
489
#
490
# Description     : Import a new version of a package
491
#                   Take great care to reuse file-versions that are already in
492
#                   the  package
493
#
369 dpurdie 494
#                   Intended to allow the importation of multiple
311 dpurdie 495
#                   versions of a package
496
#
497
# Inputs          : 
498
#
499
# Returns         : 
500
#
501
sub ImportPackage
502
{
503
    Message ("Import Package Version" );
504
 
505
    #
506
    #   Options
507
    #
508
    my $opt_package;
509
    my $opt_dir;
510
    my $opt_label;
511
    my $opt_replace = 0;
512
    my $opt_reuse;
513
    my $opt_workdir = "SvnImportDir";
514
    my $opt_delete = 1;
379 dpurdie 515
    my $opt_author;
516
    my $opt_date;
517
    my $opt_log = '';
518
    my $opt_branch;
519
    my $opt_datafile;
311 dpurdie 520
 
521
    #
522
    #   Other globals
523
    #
524
    my $url_label;
379 dpurdie 525
    my $url_branch;
311 dpurdie 526
 
527
    #
528
    #   Configuration options
529
    #
530
    my $result = GetOptions (
379 dpurdie 531
                    'help:+'        => \$opt_help,
532
                    'manual:3'      => \$opt_help,
533
                    'verbose:+'     => \$opt_verbose,
534
                    'package=s'     => \$opt_package,
535
                    'dir=s'         => \$opt_dir,
536
                    'label=s'       => \$opt_label,
537
                    'branch=s'      => \$opt_branch,
538
                    'replace'       => \$opt_replace,
539
                    'reuse'         => \$opt_reuse,
540
                    'workspace=s'   => \$opt_workdir,
541
                    'delete!'       => \$opt_delete,
542
                    'author=s'      => \$opt_author,
543
                    'date=s'        => \$opt_date,
544
                    'log=s'         => \$opt_log,
545
                    'datafile=s'    => \$opt_datafile,
311 dpurdie 546
 
547
                    #
548
                    #   Update documentation at the end of the file
549
                    #
550
                    ) || Error ("Invalid command line" );
551
 
552
    #
553
    #   Insert defaults
341 dpurdie 554
    #   User can specify base package via -package or a non-options argument
311 dpurdie 555
    #
556
    $opt_package = $ARGV[0] unless ( $opt_package );
379 dpurdie 557
    unlink $opt_datafile if ( defined $opt_datafile );
311 dpurdie 558
 
559
    #
560
    #   Subcommand specific help
561
    #
562
    SubCommandHelp( $opt_help, "Import directory to a Package")
563
        if ($opt_help || ! $opt_package );
564
 
565
    #
369 dpurdie 566
    #   Alter the error reporting parameters
311 dpurdie 567
    #
568
    ErrorConfig( 'verbose' => $opt_verbose );
569
 
570
    #
571
    #   Configure the error reporting process now that we have the user options
572
    #
573
    Error ("No package URL specified") unless ( $opt_package );
574
    Error ("No base directory specified") unless ( $opt_dir );
575
    Error ("Invalid base directory: $opt_dir") unless ( -d $opt_dir );
576
 
577
    #
578
    #   Create an SVN session
579
    #
580
    my $svn = NewSessionByUrl ( $opt_package );
581
 
582
    #
583
    #   Ensure that the required label is available
584
    #
585
    if ( $opt_label )
586
    {
587
        $opt_label = SvnIsaSimpleLabel ($opt_label);
588
        $url_label = $svn->BranchName( $opt_label, 'tags' );
589
        $svn->SvnValidateTarget (
590
                        'target' => $url_label,
591
                        'available' => 1,
592
                        ) unless ( $opt_replace );
593
    }
594
 
595
    #
379 dpurdie 596
    #   Validate the required branch
597
    #   It will be created if it doesn't exist
598
    #
599
    if ( $opt_branch )
600
    {
601
        $opt_branch = SvnIsaSimpleLabel($opt_branch);
602
        $url_branch = $svn->BranchName( $opt_branch, 'branches' );
385 dpurdie 603
        my $rv = $svn->SvnValidateTarget (
604
                        'cmd'    => 'SvnImporter. Create branch',
379 dpurdie 605
                        'target' => $url_branch,
606
                        'create' => 1,
607
                        );
385 dpurdie 608
        if ( $rv == 2 )
609
        {
610
            $svn->setRepoProperty('svn:author', $opt_author) if (defined ($opt_author));
611
            $svn->setRepoProperty('svn:date', $opt_date) if (defined ($opt_date));
612
        }
379 dpurdie 613
    }
614
 
615
    #
311 dpurdie 616
    #   Create a workspace based on the users package
617
    #   Allow the workspace to be reused to speed up multiple
618
    #   operations
619
    #
620
    unless ( $opt_reuse && -d $opt_workdir )
621
    {
622
        Message ("Creating Workspace");
623
        rmtree( $opt_workdir );
624
 
625
        $svn->SvnValidatePackageRoot ();
626
        #DebugDumpData( 'Svn', $svn );
627
        $svn->SvnValidateTarget (
628
                            'cmd'    => 'SvnImporter',
629
                            'target' => $svn->Full,
630
                            'require' => 1,
631
                            );
632
 
379 dpurdie 633
        my $url_co = $opt_branch ? $url_branch : $svn->Full . '/trunk';
634
        $svn->SvnCo ( $url_co, $opt_workdir );
311 dpurdie 635
        Error ("Cannot locate the created Workspace")
636
            unless ( -d $opt_workdir );
637
    }
638
    else
639
    {
640
        Message ("Reusing Workspace");
641
    }
642
 
643
    #
644
    #   Determine differences between the two folders
645
    #       Create structures for each directory
646
    #
647
    Message ("Determine Files in packages");
648
 
649
    my $search = JatsLocateFiles->new("--Recurse=1",
650
                                       "--DirsToo",
651
                                       "--FilterOutRe=/\.svn/",
652
                                       "--FilterOutRe=/\.svn\$",
653
                                       "--FilterOutRe=^/${opt_workdir}\$",
654
                                       "--FilterOutRe=^/${opt_workdir}/",
655
                                       );
656
    my @ws = $search->search($opt_workdir);
657
    my @dir = $search->search($opt_dir);
658
 
659
    #Information ("WS Results", @ws);
660
    #Information ("DIR Results", @dir);
661
 
662
    #
663
    #   Create a hash the Workspace and the User dir
664
    #   The key will be file names
665
    #
666
    my %ws;  map ( $ws{$_} = 1 , @ws );
667
    my %dir; map ( $dir{$_} = 1 , @dir );
668
 
669
    #
670
    #   Create a hash of common elements
671
    #   Removing then from the other two
672
    #
673
    my %common;
674
    foreach ( keys %ws )
675
    {
676
        next unless ( exists $dir{$_} );
677
        $common{$_} = 1;
678
        delete $ws{$_};
679
        delete $dir{$_};
680
    }
681
 
682
    #DebugDumpData( 'WS', \%ws );
683
    #DebugDumpData( 'DIR', \%dir );
684
    #DebugDumpData( 'COMMON', \%common );
685
 
686
    #
379 dpurdie 687
    #   Need to consider the case where a file has been replaced with a directory
688
    #   and visa-versa. Delete files and directories first.
689
    #
690
    #
691
    #   Remove files
692
    #   Sort in reverse. This will ensure that we process directory
693
    #   contents before directories
694
    #
695
    my @rm_files = reverse sort keys %ws;
696
    if ( @rm_files )
697
    {
698
        foreach my $file ( @rm_files  )
699
        {
700
            Verbose ("Removing $file");
701
            unlink "$opt_workdir/$file";
702
        }
703
 
704
        #
705
        #   Inform Subversion about the removed files
706
        #
707
        my $base = 0;
708
        my $num = $#rm_files;
709
        Message ("Update the workspace: Removed " . ($num + 1) . " Files");
710
 
711
        while ( $base <= $num )
712
        {
713
            my $end = $base + 200;
714
            $end = $num if ( $end > $num );
715
 
716
            $svn->SvnCmd ( 'delete', map ("$opt_workdir/$_@", @rm_files[$base .. $end] ),
717
                            { 'error' => 'Deleting files from workspace' } );
718
 
719
            $base = $end + 1;
720
        }
721
    }
722
 
723
    #
311 dpurdie 724
    #   Add New Files
725
    #   Won't add empty directories at this point
726
    #
727
    #   Process by sorted list
728
    #   This will ensure we process parent directories first
729
    #
730
    my @added = sort keys %dir;
731
    if ( @added )
732
    {
733
        foreach my $file ( @added  )
734
        {
735
            my $src = "$opt_dir/$file";
736
            my $target = "$opt_workdir/$file";
737
 
738
            if ( -d $src )
739
            {
379 dpurdie 740
                Verbose ("Adding directory: $file");
311 dpurdie 741
                mkdir ( $target ) unless (-d $target);
742
            }
743
            else
744
            {
745
 
746
                my $path = dirname ( $target);
747
                mkdir ( $path ) unless (-d $path);
748
 
749
                Verbose ("Adding $file");
750
                unless (File::Copy::copy( $src, $target ))
751
                {
752
                    Error("Failed to transfer file [$file]: $!");
753
                }
754
            }
755
        }
756
 
757
        #
758
        #   Inform Subversion about the added files
759
        #   The command line does have a finite length, so add them 200 at a
760
        #   time.
761
        #
762
 
763
        my $base = 0;
764
        my $num = $#added;
379 dpurdie 765
        Message ("Update the workspace: Added " . (1 + $num) . " files");
311 dpurdie 766
 
767
        while ( $base <= $num )
768
        {
769
            my $end = $base + 200;
770
            $end = $num if ( $end > $num );
771
 
772
            $svn->SvnCmd ( 'add'
773
                            , '--depth=empty'
774
                            , '--parents'
379 dpurdie 775
                            , map ("$opt_workdir/$_@", @added[$base .. $end] ),
311 dpurdie 776
                            { 'error' => 'Adding files to workspace' } );
777
 
778
            $base = $end + 1;
779
        }
780
    }
781
 
782
    #
783
    #   The common files may have changed
784
    #   Simply copy them all in and let subversion figure it out
785
    #
786
    foreach my $file ( sort keys %common  )
787
    {
788
        my $src = "$opt_dir/$file";
789
        my $target = "$opt_workdir/$file";
790
 
791
        next if ( -d $src );
792
        if ( File::Compare::compare ($src, $target) )
793
        {
794
            Verbose ("Transfer $file");
795
            unlink $target;
796
            unless (File::Copy::copy( $src, $target ))
797
            {
798
                Error("Failed to transfer file [$file]: $!",
799
                      "Src: $src",
800
                      "Tgt: $target");
801
            }
802
        }
803
    }
804
 
805
    #
806
    #   Commit the workspace
807
    #   This will go back onto the trunk
808
    #
809
    $svn = NewSessionByWS( $opt_workdir );
379 dpurdie 810
    my $pkgPath = $svn->Path();
387 dpurdie 811
 
379 dpurdie 812
    my $ciComment = "$pkgPath: Checkin by Svn Import";
813
    $ciComment .= "\n" . $opt_log if ( $opt_log );
814
    $ciComment =~ s~\r\n~\n~g;
387 dpurdie 815
    $ciComment =~ s~\r~\n~g;
816
    $ciComment = encode('UTF-8', $ciComment, Encode::FB_DEFAULT);
817
 
379 dpurdie 818
    $svn->SvnCi ('comment' => $ciComment, 'allowSame' => 1 );
381 dpurdie 819
    Message ("Repository Ref: " . $svn->RmRef) unless( $opt_label );
379 dpurdie 820
    $svn->setRepoProperty('svn:author', $opt_author) if (defined ($opt_author));
821
    $svn->setRepoProperty('svn:date', $opt_date) if (defined ($opt_date));
311 dpurdie 822
 
823
    #
824
    #   Label the result
825
    #   The workspace will have been updated, so we can use it as the base for
826
    #   the labeling process
827
    #
828
    if ( $opt_label )
829
    {
830
        $svn->SvnCopyWs (
831
                       target => $url_label,
832
                       'noswitch' => 1,
833
                       'replace' => $opt_replace,
379 dpurdie 834
                       'comment' => "$pkgPath: Tagged by Jats Svn Import",
311 dpurdie 835
                       );
836
        Message ("Repository Ref: " . $svn->RmRef);
379 dpurdie 837
        $svn->setRepoProperty('svn:author', $opt_author) if (defined ($opt_author));
838
        $svn->setRepoProperty('svn:date', $opt_date) if (defined ($opt_date));
311 dpurdie 839
    }
840
 
841
    #
842
    #   Clean up
843
    #
844
    if ( $opt_delete && ! $opt_reuse )
845
    {
846
        Message ("Delete Workspace");
847
        rmtree( $opt_workdir );
848
    }
379 dpurdie 849
 
850
    #
851
    #   Automation data transfer
852
    #
853
    if ( defined $opt_datafile )
854
    {
855
        my $data = JatsProperties::New();
856
 
857
        $data->setProperty('Command'        , 'ImportPackage');
858
        $data->setProperty('Label'          , $opt_label);
859
        $data->setProperty('subversion.tag' , $svn->RmRef);
860
 
861
        $data->Dump('InfoFile') if ($opt_verbose);
862
        $data->store( $opt_datafile );
863
    }
864
 
311 dpurdie 865
    $opr_done = 1;
866
}
867
 
868
#-------------------------------------------------------------------------------
385 dpurdie 869
# Function        : DeleteBranch
870
#
871
# Description     : Delete the branch that a workspace is based upon
872
#
873
# Inputs          : 
874
#
875
# Returns         : 
876
#
877
sub DeleteBranch
878
{
879
    my $opt_path;
880
    my $opt_error = 0;
881
    #
882
    #   Parse more options
883
    #
884
    GetOptions (
885
                "help:+"        => \$opt_help,
886
                "manual:3"      => \$opt_help,
887
                "path:s"        => \$opt_path,
888
                ) || Error ("Invalid command line" );
889
 
890
    #
891
    #   Subcommand specific help
892
    #
893
    SubCommandHelp( $opt_help, "Delete Branch") if ($opt_help);
894
 
895
    #
896
    #   Sanity Tests
897
    #
898
    Message ("Delete Workspace Branch" );
899
    Error ("Too many arguments: @ARGV") if ( $#ARGV >= 0 );
900
 
901
    #
902
    #   Do all the hard work
903
    #
904
    $opt_path = '.' unless ( defined $opt_path );
905
    my $uref = NewSessionByWS($opt_path, 0, 1);
906
    my $ws_root = $uref->SvnLocateWsRoot(1);
907
    my $ws_url = $uref->FullWs();
908
 
909
    #
910
    #   Must be a branch
911
    #
912
    Error ("Workspace is not based on a branch")
913
        unless ( $ws_url =~ m ~/branches/~ );
914
 
915
    Message ("Deleting: " . $uref->{WSURL} );
916
    $uref->SvnDelete (
917
                      'target'    => $ws_url,
918
                      'comment'   => [$uref->Path().": Delete Branch",'Deleted by user command: jats svn delete-branch'],
919
                      );
920
    $opr_done = 1;
921
}
922
 
923
 
924
#-------------------------------------------------------------------------------
311 dpurdie 925
# Function        : SubCommandHelp
926
#
927
# Description     : Provide help on a subcommand
928
#
929
# Inputs          : $help_level             - Help Level 1,2,3
930
#                   $topic                  - Topic Name
931
#
932
# Returns         : This function does not return
933
#
934
sub SubCommandHelp
935
{
936
    my ($help_level, $topic) = @_;
937
    my @sections;
938
    #
939
    #   Spell out the section we want to display
940
    #
941
    #   Note:
942
    #   Due to bug in pod2usage can't use 'head1' by itself
943
    #   Each one needs a subsection.
944
    #
945
    push @sections, qw( NAME SYNOPSIS ) ;
946
    push @sections, qw( ARGUMENTS OPTIONS ) if ( $help_level > 1 );
947
    push @sections, qw( DESCRIPTION )       if ( $help_level > 2 );
948
 
949
    #
950
    #   Extract section from the POD
951
    #
952
    pod2usage({-verbose => 99,
953
               -noperldoc => 1,
954
               -sections => $topic . '/' . join('|', @sections) } );
955
}
956
 
957
 
958
 
959
#-------------------------------------------------------------------------------
960
#   Documentation
961
#   NOTE
962
#
963
#   Each subcommand MUST have
964
#   head1 section as used by the subcommand
965
#       This should be empty, as the contents will NOT be displayed
966
#   head2 sections called
967
#       NAME SYNOPSIS ARGUMENTS OPTIONS DESCRIPTION
968
#
969
#=head1 xxxxxx
970
#=head2 NAME
971
#=head2 SYNOPSIS
972
#=head2 ARGUMENTS
973
#=head2 OPTIONS
974
#=head2 DESCRIPTION
975
#
976
 
977
=pod
978
 
361 dpurdie 979
=for htmltoc    GENERAL::Subversion::
980
 
311 dpurdie 981
=head1 NAME
982
 
983
jats svn - Miscellaneous SubVersion Operations
984
 
985
=head1 SYNOPSIS
986
 
987
jats svn [options] command [command options]
988
 
989
 Options:
990
    -help[=n]              - Help message, [n=1,2,3]
991
    -man                   - Full documentation [-help=3]
992
    -verbose[=n]           - Verbose command operation
993
 
994
 Common Command Options:
995
    All command support suboptions to provide command specific help
996
 
997
    -help[=n]              - Help message, [n=1,2,3]
998
    -man                   - Full documentation [-help=3]
999
 
1000
 Commands are:
363 dpurdie 1001
    test                   - Test access to subversion
369 dpurdie 1002
    paths                  - Display Subversion tag to URL conversions
311 dpurdie 1003
    ls URL                 - List Repo contents for URL
369 dpurdie 1004
    tag [URL]              - Convert URL or Path to a Release Manager Tag
1005
    url [TAG]              - Convert TAG or Path to a Subversion URL
311 dpurdie 1006
    delete-package URL     - Delete Package Subtree
385 dpurdie 1007
    delete-branch          - Delete a Development Branch
311 dpurdie 1008
    create URL             - Create a new package at URL
1009
    import URL             - Import files to package at URL
1010
 
1011
 Use the command
1012
    jats svn command -h
1013
 for command specific help
1014
 
1015
 
1016
=head1 OPTIONS
1017
 
1018
=over
1019
 
1020
=item B<-help[=n]>
1021
 
1022
Print a help message and exit. The level of help may be either 1, 2 or
1023
3 for a full manual.
1024
 
1025
This option may be specified multiple times to increment the help level, or
1026
the help level may be directly specified as a number.
1027
 
1028
=item B<-man>
1029
 
1030
This is the same as '-help=3'.
1031
The complete help is produced in a man page format.
1032
 
1033
=item B<--verbose[=n]>
1034
 
1035
This option will increase the level of verbosity of the commands.
1036
 
1037
If an argument is provided, then it will be used to set the level, otherwise the
1038
existing level will be incremented. This option may be specified multiple times.
1039
 
1040
=back
1041
 
1042
=head1 DESCRIPTION
1043
 
1044
This program provides a number of useful Subversion based operations.
1045
 
363 dpurdie 1046
=head1 Test Subversion
1047
 
1048
=head2 NAME
1049
 
1050
Test Subversion
1051
 
1052
=head2 SYNOPSIS
1053
 
1054
    jats svn test
1055
 
1056
=head2 DESCRIPTION
1057
 
1058
This command will ensure that the subversion command line utility can be
1059
located. The command will report the version of the svn client found.
1060
 
369 dpurdie 1061
=head1 Subversion Paths
1062
 
1063
=head2 NAME
1064
 
1065
Subversion Paths
1066
 
1067
=head2 SYNOPSIS
1068
 
1069
    jats svn paths
1070
 
1071
=head2 DESCRIPTION
1072
 
1073
This command will display the base Tags and associated URLs that are used by
1074
JATS to convert a 'Subversion Tag' into a full URLs that will be used to access
1075
a physical repository.
1076
 
1077
The 'Tags' configuration is site-specific.
1078
 
311 dpurdie 1079
=head1 List Repository
1080
 
363 dpurdie 1081
=head2 NAME
1082
 
1083
List Repository
1084
 
1085
=head2 SYNOPSIS
1086
 
1087
    jats svn ls <URL>
1088
 
1089
=head2 DESCRIPTION
1090
 
311 dpurdie 1091
This command will take a URL and perform a 'svn' list operation. The URL will
1092
be expanded to include the site specific repository.
1093
 
369 dpurdie 1094
=head1 Url to Tag
1095
 
1096
=head2 NAME
1097
 
1098
Url to Tag
1099
 
1100
=head2 SYNOPSIS
1101
 
1102
    jats svn tag [Option] [tag]
1103
 
1104
 Options:
1105
    -help[=n]              - Help message, [n=1,2,3]
1106
    -man                   - Full documentation [-help=3]
1107
    -path=path             - Convert specified path
1108
    -url=url               - Convert specified URL
1109
 
1110
=head2 DESCRIPTION
1111
 
1112
This command will convert a URL or a PATH to a Subversion Tag that can
1113
be used within the remainder of the build system. If no PATH or URL is provided,
1114
then the command uses a path of the current directory.
1115
 
1116
The command will convert either a PATH or a URL. It will not do both.
1117
 
1118
The command will use the configured Subversion URL prefixes to create the Tag.
1119
 
1120
If a PATH is to be converted, then the PATH must address a Subversion workspace.
1121
The conversion will return a Tag to the root of the Workspace and Peg it to
1122
the last committed version. The command will not determine if the workspace
1123
contains modified files.
1124
 
1125
If a URL is to be converted, then the resultant value should be used with
1126
caution. The result is only as good as the provided URL and may not address
1127
the root of a package.
1128
 
1129
=head1 Tag to Url
1130
 
1131
=head2 NAME
1132
 
1133
Tag to Url
1134
 
1135
=head2 SYNOPSIS
1136
 
1137
    jats svn url [Option] [url]
1138
 
1139
 Options:
1140
    -help[=n]              - Help message, [n=1,2,3]
1141
    -man                   - Full documentation [-help=3]
1142
    -path=path             - Convert specified path
1143
    -url=url               - Convert specified URL
1144
 
1145
=head2 DESCRIPTION
1146
 
1147
This command will convert a TAG or a PATH to a full URL that can be used
1148
directly by Subversion. If no PATH or TAG is provided, then the command uses a
1149
path of the current directory.
1150
 
1151
The command will convert either a TAG or a URL. It will not do both.
1152
 
1153
The command will use the configured Subversion URL prefixes to expand the TAG.
1154
 
1155
If a PATH is to be converted, then the PATH must address a Subversion workspace.
1156
The conversion will return a URL to the root of the Workspace and Peg it to
1157
the last committed version. The command will not determine if the workspace
1158
contains modified files.
1159
 
1160
If a TAG is to be converted, then the resultant value should be used with
1161
caution. The result is only as good as the provided URL and may not address
1162
the root of a package.
1163
 
311 dpurdie 1164
=head1 Delete a Package
1165
 
1166
=head2 NAME
1167
 
1168
Delete a Package
1169
 
1170
=head2 SYNOPSIS
1171
 
1172
jats svn delete-package URL [options]
1173
 
1174
 Options:
1175
    -help[=n]              - Help message, [n=1,2,3]
1176
    -man                   - Full documentation [-help=3]
1177
    -verbose[=n]           - Verbose command operation
1178
 
1179
=head2 ARGUMENTS
1180
 
1181
The command takes one argument: The URL of the desired package.
1182
This may be be:
1183
 
1184
=over
1185
 
1186
=item * A full URL
1187
 
1188
Complete with protocol and path information.
1189
 
1190
=item * A simple URL
1191
 
1192
JATS will prepend the site-specific repository location to the user provided URL
1193
 
1194
=back
1195
 
1196
=head2 OPTIONS
1197
 
1198
This command has no significant options, other than the general help options.
1199
 
1200
=head2 DESCRIPTION
1201
 
1202
This command will delete a package from the repository. It will ensure
1203
that the package is a valid package, before it is deleted.
1204
 
1205
The command is intended to be used by test scripts, rather than users.
1206
 
385 dpurdie 1207
=head1 Delete Branch
1208
 
1209
=head2 NAME
1210
 
1211
Delete the Workspace Branch
1212
 
1213
=head2 SYNOPSIS
1214
 
1215
jats svn delete-branch [options]
1216
 
1217
 Options:
1218
    -help[=n]              - Help message, [n=1,2,3]
1219
    -man                   - Full documentation [-help=3]
1220
    -verbose[=n]           - Verbose command operation
1221
    -path=path             - Target workspace
1222
 
1223
=head2 ARGUMENTS
1224
 
1225
The command takes no arguments.
1226
 
1227
=head2 OPTIONS
1228
 
1229
=over
1230
 
1231
=item B<-path=path>
1232
 
1233
This options specifies the path of the target workspace. If not provided the
1234
command will use the current directory.
1235
 
1236
=back
1237
 
1238
=head2 DESCRIPTION
1239
 
1240
This command will delete the branch associated with the workspace in the
1241
specified path. It is intended to simplify the deletion of Private or
1242
Development branches.
1243
 
1244
If the workspace is not linked to a 'branch' then the command will fail.
1245
 
311 dpurdie 1246
=head1 Create a Package Version
1247
 
1248
=head2 NAME
1249
 
1250
Create a Package Version
1251
 
1252
=head2 SYNOPSIS
1253
 
1254
jats svn [options] create URL [command options]
1255
 
1256
 Options:
1257
    -help[=n]               - Help message, [n=1,2,3]
1258
    -man                    - Full documentation [-help=3]
1259
    -verbose[=n]            - Verbose command operation
1260
 
1261
 Command Options
1262
    -help[=n]               - Provide command specific help
1263
    -import=nnn             - Import directory tree
1264
    -label=nnn              - Label it (trunk import only)
1265
    -new                    - Package must not exist
1266
    -replace                - Replace any existing versions
1267
    -trunk                  - Import to trunk
1268
    -tags=nnn               - Import to tags
1269
    -branch=nnn             - Import to branches
1270
 
1271
=head2 ARGUMENTS
1272
 
1273
The command takes one argument: The URL of the desired package.
1274
This may be be:
1275
 
1276
=over
1277
 
1278
=item * A full URL
1279
 
1280
Complete with protocol and path information.
1281
 
1282
=item * A simple URL
1283
 
1284
JATS will prepend the site-specific repository location to the user provided URL
1285
 
1286
=back
1287
 
1288
=head2 OPTIONS
1289
 
1290
=over
1291
 
1292
=item -help[=n]
1293
 
1294
Print a help message and exit. The level of help may be either 1, 2 or 3.
1295
 
1296
This option may be specified multiple times to increment the help level, or
1297
the help level may be directly specified as a number.
1298
 
1299
=item -import=nnn
1300
 
1301
This option specifies the path of a subdirectory tree to import into the newly
1302
created package. In not provided, then only a package skeleton will be created.
1303
 
1304
=item -label=nnn
1305
 
1306
This option specifies a label to place the imported source, if the source is
1307
being imported to the 'trunk' of the package.
1308
 
1309
=item -new
1310
 
1311
This option specifies that the named package MUST not exist at all.
1312
 
1313
=item -replace
1314
 
1315
This option allows the program to replace any existing versions of the
1316
imported source. It will allow the deletion of any existing trunk, tags or
1317
branches.
1318
 
1319
=item -trunk
1320
 
1321
This option specifies that imported source will be placed on the trunk of the
1322
package. This is the default mode of import.
1323
 
1324
The options -trunk, -tags and -branch are mutually exclusive.
1325
 
1326
=item -tags=nnn
1327
 
1328
This option specifies that imported source will be placed directly on the
1329
named tag of the package.
1330
 
1331
The options -trunk, -tags and -branch are mutually exclusive.
1332
 
1333
=item -branch=nnn
1334
 
1335
This option specifies that imported source will be placed directly on the
1336
named branch of the package.
1337
 
1338
The options -trunk, -tags and -branch are mutually exclusive.
1339
 
1340
=back
1341
 
1342
=head2 DESCRIPTION
1343
 
1344
This command will create a new package within a repository. It will ensure
1345
that the package contains the three required subdirectories: trunk, tags and
1346
branches.
1347
 
1348
The command will also ensure that packages are not placed at inappropriate
1349
locations within the repository. It is not correct to place a package within
1350
another package.
1351
 
1352
The command will, optionally, import a directory tree into the repository and,
1353
optionally, label the package.
1354
 
1355
The package body may be imported to the 'trunk' or to a branch or a tag.
1356
By default the data will be imported to the trunk and may be labeled (tagged).
1357
 
1358
Options allow the targets to be deleted if they exist or to ensure that they
1359
are not present.
1360
 
1361
The command does not attempt to merge file versions within the repository. It
1362
may result in multiple instances of a file within the repository. Use only for
341 dpurdie 1363
simple imports. Use the 'import' command for more sophisticated import requirements.
311 dpurdie 1364
 
1365
=head1 Import directory to a Package
1366
 
1367
=head2 NAME
1368
 
1369
Import directory to a Package
1370
 
1371
=head2 SYNOPSIS
1372
 
1373
jats svn [options] import URL [command options]
1374
 
1375
 Options:
1376
    -help[=n]               - Help message, [n=1,2,3]
1377
    -man                    - Full documentation [-help=3]
1378
    -verbose[=n]            - Verbose command operation
1379
 
1380
 Command Options
1381
    -help[=n]               - Command specific help, [n=1,2,3]
1382
    -verbose[=n]            - Verbose operation
1383
    -package=name           - Name of source package
1384
    -dir=path               - Path to new version
379 dpurdie 1385
    -label=label            - Label the result
1386
    -branch=branchName      - Base import on a branch
311 dpurdie 1387
    -replace                - Allow the label to be replaced
1388
    -reuse                  - Reuse the import directory
1389
    -workspace=path         - Path and name of alternate workspace
1390
    -[no]delete             - Deletes workspace after use. Default:yes
379 dpurdie 1391
    -author=name            - Force author of changes
1392
    -date=dateString        - Force date of changes
1393
    -log=text               - Append text to the commit message
1394
    -datafile=path          - Export tag data for automation
311 dpurdie 1395
 
379 dpurdie 1396
 
311 dpurdie 1397
=head2 ARGUMENTS
1398
 
1399
The command takes one argument: The URL of the desired package.
1400
This may be be:
1401
 
1402
=over
1403
 
1404
=item * A full URL
1405
 
1406
Complete with protocol and path information.
1407
 
1408
=item * A simple URL
1409
 
1410
JATS will prepend the site-specific repository location to the user provided URL
1411
 
1412
=back
1413
 
1414
=head2 OPTIONS
1415
 
1416
=over
1417
 
1418
=item -help[=n]
1419
 
1420
Print a help message and exit. The level of help may be either 1, 2 or 3.
1421
 
1422
This option may be specified multiple times to increment the help level, or
1423
the help level may be directly specified as a number.
1424
 
1425
=item -verbose[=n]
1426
 
1427
This option will increase the level of verbosity of the utility.
1428
 
1429
If an argument is provided, then it will be used to set the level, otherwise the
1430
existing level will be incremented. This option may be specified multiple times.
1431
 
1432
 
1433
=item -package=name
1434
 
1435
Either this option or a bare URL on the command line must be provided. It
1436
specifies the repository and package to be used as a basis for the work.
1437
 
1438
=item -dir=path
1439
 
1440
This option is mandatory. It specifies the path to a local directory that
1441
contains a version of the software to be checked in.
1442
 
1443
=item -label=name
1444
 
1445
The resulting software version will be labeled with this tag, if it is provided.
1446
 
383 dpurdie 1447
A label name of TIMESTAMP will be treated in special manner. The name will be
1448
replaced with a unique name based on the users name and the current date time.
1449
 
379 dpurdie 1450
=item -branch=branchName
1451
 
1452
This option will cause the importation to be referenced to the named branch.
1453
If the branch does not exist it will be created. If it does exist then it will
1454
be used.
1455
 
1456
If this option is not specified, then the importation will be based on the 'trunk'.
1457
 
1458
If the Workspace is provided, then it will be used independently of this option.
1459
 
383 dpurdie 1460
A branchName of TIMESTAMP will be treated in special manner. The name will be
1461
replaced with a unique name based on the users name and the current date time.
1462
 
311 dpurdie 1463
=item -replace
1464
 
1465
This option, if provided, allows the label to be replaced.
1466
 
1467
=item -reuse
1468
 
1469
This option can be used to speed the creation of multiple versions in a scripted
1470
environment. The option allows the utility to reuse the workspace if it exists.
1471
 
1472
=item -workspace=path
1473
 
1474
This option specifies an alternate workspace directory to create and use. The
1475
default directory is "SvnImportDir" within the users current directory.
1476
 
1477
=item [no]delete
1478
 
341 dpurdie 1479
This option control the deletion of the workspace directory. By default the
311 dpurdie 1480
directory will be deleted, unless re-use is also used.
1481
 
379 dpurdie 1482
=item -author=name
1483
 
1484
This option will force the author of changes as recorded in the repository.
385 dpurdie 1485
The repository must be configured to allow such changes.
379 dpurdie 1486
 
1487
This option may not work for non-admin users.
1488
 
1489
=item -date=dateString
1490
 
1491
This option will force the date of the changes as recorded in the repository.
385 dpurdie 1492
The repository must be configured to allow such changes.
379 dpurdie 1493
The dateString is in a restricted ISO 8601 format: ie 2009-02-12T00:44:04.921324Z
1494
 
1495
This option may not work for non-admin users.
1496
 
1497
=item -log=text
1498
 
1499
This option will append the specified text to the commit message.
1500
The first line of the commit message is fixed by the import tool.
1501
 
1502
=item -datafile=path
1503
 
1504
This option will cause the utility to create a data file to record the import
1505
tag. It is used for automation of the import process.
1506
 
311 dpurdie 1507
=back
1508
 
1509
=head2 DESCRIPTION
1510
 
1511
Import a new version of a package to the trunk of the package. The utility
1512
will only import changed files so that file history is preserved within the
1513
repository.
1514
 
1515
This utility is used import software from another version control system
1516
The utility will:
1517
 
1518
=over
1519
 
361 dpurdie 1520
=item *
311 dpurdie 1521
 
361 dpurdie 1522
Create a Work Space based on the current package version
1523
 
379 dpurdie 1524
The 'trunk' of the named package will be used as the base for the workspace,
1525
unless modified with the -branch option.
311 dpurdie 1526
 
361 dpurdie 1527
=item *
311 dpurdie 1528
 
361 dpurdie 1529
Update files and directories
1530
 
311 dpurdie 1531
Determines the files and directories that have been added and deleted and
1532
update the Workspace to reflect the new structure.
1533
 
361 dpurdie 1534
=item *
311 dpurdie 1535
 
361 dpurdie 1536
Check in the new version
311 dpurdie 1537
 
361 dpurdie 1538
=item *
1539
 
1540
Label the new version
1541
 
311 dpurdie 1542
=back
1543
 
1544
=cut
1545