Subversion Repositories DevTools

Rev

Rev 2424 | Rev 2652 | Go to most recent revision | Details | Compare with Previous | 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
use Pod::Usage;                                 # required for help support
26
use Getopt::Long qw(:config require_order);     # Stop on non-option
27
use Cwd;
28
use File::Path;
29
use File::Copy;
30
use File::Basename;
31
use File::Compare;
387 dpurdie 32
use Encode;
311 dpurdie 33
 
34
my $VERSION = "1.0.0";                          # Update this
35
 
36
#
37
#   Options
38
#
39
my $opt_debug   = $ENV{'GBE_DEBUG'};            # Allow global debug
40
my $opt_verbose = $ENV{'GBE_VERBOSE'};          # Allow global verbose
41
my $opt_help = 0;
42
 
43
#
44
#   Globals
45
#
46
my $opr_done;                                   # User has done something
47
 
48
#-------------------------------------------------------------------------------
49
# Function        : Mainline Entry Point
50
#
51
# Description     :
52
#
53
# Inputs          :
54
#
55
my $result = GetOptions (
56
                "help:+"        => \$opt_help,              # flag, multiple use allowed
57
                "manual:3"      => \$opt_help,              # flag
58
                "verbose:+"     => \$opt_verbose,           # flag, multiple use allowed
59
 
60
                );
61
 
62
                #
63
                #   UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!
64
                #
65
 
66
#
67
#   Process help and manual options
68
#
69
pod2usage(-verbose => 0, -message => "Version: $VERSION") if ($opt_help == 1 || ! $result);
70
pod2usage(-verbose => 1) if ($opt_help == 2 );
71
pod2usage(-verbose => 2) if ($opt_help > 2);
72
 
73
#
74
#   Configure the error reporting process now that we have the user options
75
#
76
ErrorConfig( 'name'    =>'SVN',
77
             'verbose' => $opt_verbose,
78
            );
79
 
80
#
369 dpurdie 81
#   Reconfigure the options parser to allow subcommands to parse options
311 dpurdie 82
#
83
Getopt::Long::Configure('permute');
84
 
85
#
86
#   Process command
87
#   First command line argument is a subversion command
88
#
89
my $cmd = shift @ARGV || "help";
90
CreatePackage()                        if ( $cmd =~ m/^create/ );
2048 dpurdie 91
CreateBranch()                         if ( $cmd =~ m/^branch/ );
92
SwitchBranch()                         if ( $cmd =~ m/^switch/ );
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
#
2048 dpurdie 110
# Inputs          :
369 dpurdie 111
#
2048 dpurdie 112
# Returns         :
369 dpurdie 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
 
1348 dpurdie 208
    Message ("Tag is  : " . $uref->RmRef() );
209
    Message ("Vcs Tag : " . $uref->SvnTag  );
2048 dpurdie 210
 
369 dpurdie 211
    $opr_done = 1;
212
}
213
#-------------------------------------------------------------------------------
214
# Function        : ShowUrl
215
#
216
# Description     : Convert a TAG into a URL
217
#                   Show the current workspace URL
218
#
219
# Inputs          : tag                     - Tag to convert (optional)
220
#                   Options
221
#                       -help[=n]           - Show help
222
#                       -man                - Show manual
223
#                       -tag=tag            - Convert TAG
224
#                       -path=path          - Convert Workspace
225
#
226
# Returns         : Nothing
227
#
228
sub ShowUrl
229
{
230
    my $opt_path;
231
    my $opt_tag;
232
 
233
    #
234
    #   Parse more options
235
    #
236
    GetOptions (
237
                "help:+"        => \$opt_help,
238
                "manual:3"      => \$opt_help,
239
                "path:s"        => \$opt_path,
240
                "tag:s"         => \$opt_tag,
241
                ) || Error ("Invalid command line" );
242
 
243
    #
244
    #   Subcommand specific help
245
    #
246
    SubCommandHelp( $opt_help, "Tag to Url") if ($opt_help);
247
 
248
    #
249
    #   Bare argument is a TAG
250
    #   If no arguments provided assume a path of the current directory
251
    #
252
    $opt_tag = shift (@ARGV) if ( $#ARGV == 0 );
253
    $opt_path = '.' unless ( defined $opt_path || defined $opt_tag );
254
 
255
    #
256
    #   Sanity Tests
257
    #
258
    Error ("Cannot specify both a TAG and a PATH")
259
            if ( defined $opt_tag && defined $opt_path );
260
    Warning ("Too many arguments") if ( $#ARGV >= 0 );
261
 
262
    #   Do all the hard work
263
    #
264
    my $uref;
265
    my $url;
266
    if ( $opt_tag )
267
    {
2424 dpurdie 268
        my $path = $opt_tag;
269
        my $label;
270
 
271
        $path =~ s~^SVN::~~;
272
        if ( $path =~ m~(.+)::(.+)~ )
273
        {
274
            $path = $1;
275
            $label = $2;
276
        }
277
        $url = SvnPath2Url($path);
278
        if ( $label && $label =~ m~^\d+$~ )
279
        {
280
            $url .= '@' . $label;
281
        }
282
        elsif ( $label )
283
        {
284
            $url =~ m~(.+)(/(tags|branches|trunk)(/|$|@))~;
285
            $url = $1 . '/tags/'. $label;
286
        }
369 dpurdie 287
    }
288
    else
289
    {
290
        $uref = NewSessionByWS($opt_path, 0, 1);
291
        my $ws_root = $uref->SvnLocateWsRoot(1);
292
        $url = $uref->FullWsRev();
293
    }
294
 
295
    Message ("Url: $url");
296
    $opr_done = 1;
297
}
298
 
299
#-------------------------------------------------------------------------------
363 dpurdie 300
# Function        : TestSvn
301
#
302
# Description     : Test access to subversion
303
#
304
# Inputs          : None
305
#
306
# Returns         :
307
#
308
sub TestSvn
309
{
310
    #
311
    #   Parse more options
312
    #
313
    GetOptions (
314
                "help:+"        => \$opt_help,
315
                "manual:3"      => \$opt_help,
316
                ) || Error ("Invalid command line" );
317
 
318
    #
319
    #   Subcommand specific help
320
    #
321
    SubCommandHelp( $opt_help, "Test Subversion") if ($opt_help || $#ARGV >= 0);
322
 
323
    SvnUserCmd( '--version');
324
    $opr_done = 1;
325
}
326
#-------------------------------------------------------------------------------
311 dpurdie 327
# Function        : SvnRepoCmd
328
#
329
# Description     : Execute a SVN command, where the first argument
330
#                   is a repository specifier
331
#
332
# Inputs          : $cmd
333
#                   $repo_url
334
#                   @opts
335
#
2048 dpurdie 336
# Returns         :
311 dpurdie 337
#
338
sub SvnRepoCmd
339
{
340
    my ( $cmd, $repo_url, @opts ) = @_;
341
    my $uref = NewSessionByUrl ( $repo_url );
342
 
343
    SvnUserCmd( $cmd,
344
            $uref->Full,
345
            @opts,
346
            { 'credentials' => 1 });
2048 dpurdie 347
 
311 dpurdie 348
    $opr_done = 1;
349
}
350
 
351
#-------------------------------------------------------------------------------
352
# Function        : DeletePackage
353
#
354
# Description     : Delete a Package structure within a Repository
355
#                   Intended for test usage
356
#
357
# Inputs          : URL                 - Url to Repo + Package Base
358
#
2048 dpurdie 359
# Returns         :
311 dpurdie 360
#
361
sub DeletePackage
362
{
379 dpurdie 363
    my $opt_error = 0;
311 dpurdie 364
    #
365
    #   Parse more options
366
    #
367
    GetOptions (
368
                "help:+"        => \$opt_help,
369
                "manual:3"      => \$opt_help,
379 dpurdie 370
                "error!"       => \$opt_error,
311 dpurdie 371
                ) || Error ("Invalid command line" );
372
 
373
    #
374
    #   Subcommand specific help
375
    #
376
    SubCommandHelp( $opt_help, "Delete a Package") if ($opt_help || $#ARGV < 0);
377
 
378
    #
379
    #   Sanity Tests
380
    #
381
    Message ("Delete Entire Package Tree" );
382
    Warning ("Too many arguments: @ARGV") if ( $#ARGV >= 1 );
383
 
384
    #
385
    #   Do all the hard work
386
    #       Create
387
    #       Import
388
    #       Label
389
    #
390
    my $uref = NewSessionByUrl ( $ARGV[0] );
379 dpurdie 391
    $uref->SvnValidatePackageRoot(!$opt_error);
311 dpurdie 392
    $uref->SvnDelete (
393
                      'target'      => $uref->Full,
385 dpurdie 394
                      'comment'   => [$uref->Path().": Delete Package",'Deleted by user command: jats svn delete-package'],
379 dpurdie 395
                      'noerror'   => !$opt_error,
311 dpurdie 396
                      );
397
    $opr_done = 1;
398
}
399
 
400
#-------------------------------------------------------------------------------
401
# Function        : CreatePackage
402
#
403
# Description     : Create a Package structure within a Repository
404
#                   Optionally Import Data
405
#                   Optionally Tag the import
406
#                   Optionally Tag the import on a branch
407
#
408
# Inputs          : URL                 - Url to Repo + Package Base
409
#                   Options             - Command modifiers
410
#                       -import=path    - Import named directory
411
#                       -label=name     - Label the result
412
#                       -tag=name       - Import to Tag Only
413
#                       -branch=name    - Import to Branch only
414
#                       -new            - Must be new package
415
#                       -replace        - Replace existing
416
#
2048 dpurdie 417
# Returns         :
311 dpurdie 418
#
419
sub CreatePackage
420
{
421
    my $opt_import;
422
    my $opt_tag;
423
    my $opt_branch;
424
    my $opt_trunk;
425
    my $opt_new;
426
    my $opt_label;
427
    my $opt_replace;
428
    my $pname;
429
    my $type;
385 dpurdie 430
    my $opt_author;
431
    my $opt_date;
311 dpurdie 432
    Message ("Create New Package Version" );
433
 
434
    #
435
    #   Parse more options
436
    #
437
    GetOptions (
438
                "help:+"        => \$opt_help,
439
                "manual:3"      => \$opt_help,
440
                "verbose:+"     => \$opt_verbose,
441
                "import=s"      => \$opt_import,
442
                "new"           => \$opt_new,
443
                "branch=s"      => \$opt_branch,
444
                "trunk"         => \$opt_trunk,
1347 dpurdie 445
                "tags=s"        => \$opt_tag,
311 dpurdie 446
                "label=s"       => \$opt_label,
447
                "replace"       => \$opt_replace,
385 dpurdie 448
                'author=s'      => \$opt_author,
449
                'date=s'        => \$opt_date,
311 dpurdie 450
 
451
                ) || Error ("Invalid command line" );
452
 
453
    #
454
    #   Subcommand specific help
455
    #
456
    SubCommandHelp( $opt_help, "Create a Package Version") if ($opt_help || $#ARGV < 0);
2048 dpurdie 457
 
311 dpurdie 458
    #
369 dpurdie 459
    #   Alter the error reporting parameters
311 dpurdie 460
    #
461
    ErrorConfig( 'verbose' => $opt_verbose );
462
 
463
    #
464
    #   Sanity Tests
465
    #
466
    my $count = 0;
467
    $count++ if ( $opt_trunk );
468
    $count++ if ( $opt_branch );
469
    $count++ if ( $opt_tag );
470
    Error ("Conflicting options: -trunk, -tag, -branch") if ( $count > 1 );
471
    Error ("Nothing imported to be labeled") if ( $count && !$opt_import );
472
    Error ("Import path does not exist: $opt_import") if ( $opt_import && ! -d $opt_import );
473
    Error ("Conflicting options: new and replace") if ( $opt_new && $opt_replace );
385 dpurdie 474
    Error ("Too many command line arguments") if ( exists $ARGV[1] );
311 dpurdie 475
 
1347 dpurdie 476
    $type = 'tags/' . $opt_tag          if ( $opt_tag);
477
    $type = 'branches/' . $opt_branch   if ( $opt_branch );
478
    $type = 'trunk'                     if ( $opt_trunk);
311 dpurdie 479
 
480
    #
481
    #   Do all the hard work
482
    #       Create
483
    #       Import
484
    #       Label
485
    #
486
    my $uref = NewSessionByUrl ( $ARGV[0] );
487
    $uref->SvnCreatePackage (
488
                      'import'  => $opt_import,
489
                      'label'   => $opt_label,
490
                      'type'    => $type,
491
                      'new'     => $opt_new,
492
                      'replace' => $opt_replace,
493
                      );
385 dpurdie 494
    #
495
    # Report RmPath as using a pegged version of a new package is a bit silly
496
    #
1356 dpurdie 497
#    Message ("Repository Ref: " . $uref->RmPath);
498
#    Message ("Vcs Tag       : " . $uref->SvnTag);
1270 dpurdie 499
    if ( $uref->{REVNO} )
500
    {
501
        $uref->setRepoProperty('svn:author', $opt_author) if (defined ($opt_author));
502
        $uref->setRepoProperty('svn:date', $opt_date) if (defined ($opt_date));
503
    }
311 dpurdie 504
    $opr_done = 1;
505
}
506
 
507
#-------------------------------------------------------------------------------
508
# Function        : ImportPackage
509
#
510
# Description     : Import a new version of a package
511
#                   Take great care to reuse file-versions that are already in
512
#                   the  package
513
#
369 dpurdie 514
#                   Intended to allow the importation of multiple
311 dpurdie 515
#                   versions of a package
516
#
2048 dpurdie 517
# Inputs          :
311 dpurdie 518
#
2048 dpurdie 519
# Returns         :
311 dpurdie 520
#
521
sub ImportPackage
522
{
523
    Message ("Import Package Version" );
524
 
525
    #
526
    #   Options
527
    #
528
    my $opt_package;
529
    my $opt_dir;
530
    my $opt_label;
531
    my $opt_replace = 0;
532
    my $opt_reuse;
533
    my $opt_workdir = "SvnImportDir";
534
    my $opt_delete = 1;
379 dpurdie 535
    my $opt_author;
536
    my $opt_date;
537
    my $opt_log = '';
538
    my $opt_branch;
539
    my $opt_datafile;
1348 dpurdie 540
    my $opt_printfiles;
2424 dpurdie 541
    my $opt_commit = 1;
2616 dpurdie 542
    my $opt_nodelete;
311 dpurdie 543
 
544
    #
545
    #   Other globals
546
    #
547
    my $url_label;
379 dpurdie 548
    my $url_branch;
311 dpurdie 549
 
2616 dpurdie 550
    my $filesBase = 0;                  # Files in Base workspace
551
    my $filesDeleted = 0;               # Files Deleted
552
    my $filesAdded = 0;                 # Files Added
553
    my $dirsDeleted = 0;                # Directories Deleted
554
    my $dirsAdded = 0;                  # Directories Added
555
 
556
 
311 dpurdie 557
    #
558
    #   Configuration options
559
    #
560
    my $result = GetOptions (
379 dpurdie 561
                    'help:+'        => \$opt_help,
562
                    'manual:3'      => \$opt_help,
563
                    'verbose:+'     => \$opt_verbose,
564
                    'package=s'     => \$opt_package,
565
                    'dir=s'         => \$opt_dir,
566
                    'label=s'       => \$opt_label,
567
                    'branch=s'      => \$opt_branch,
568
                    'replace'       => \$opt_replace,
569
                    'reuse'         => \$opt_reuse,
570
                    'workspace=s'   => \$opt_workdir,
571
                    'delete!'       => \$opt_delete,
1348 dpurdie 572
                    'printfiles=i'  => \$opt_printfiles,
379 dpurdie 573
                    'author=s'      => \$opt_author,
574
                    'date=s'        => \$opt_date,
575
                    'log=s'         => \$opt_log,
576
                    'datafile=s'    => \$opt_datafile,
2424 dpurdie 577
                    'commit!'       => \$opt_commit,
2616 dpurdie 578
                    'nodelete=s'    => \$opt_nodelete,
311 dpurdie 579
 
580
                    #
581
                    #   Update documentation at the end of the file
582
                    #
583
                    ) || Error ("Invalid command line" );
584
 
585
    #
586
    #   Insert defaults
341 dpurdie 587
    #   User can specify base package via -package or a non-options argument
311 dpurdie 588
    #
589
    $opt_package = $ARGV[0] unless ( $opt_package );
379 dpurdie 590
    unlink $opt_datafile if ( defined $opt_datafile );
2048 dpurdie 591
 
311 dpurdie 592
    #
593
    #   Subcommand specific help
594
    #
595
    SubCommandHelp( $opt_help, "Import directory to a Package")
596
        if ($opt_help || ! $opt_package );
597
 
598
    #
369 dpurdie 599
    #   Alter the error reporting parameters
311 dpurdie 600
    #
601
    ErrorConfig( 'verbose' => $opt_verbose );
602
 
603
    #
604
    #   Configure the error reporting process now that we have the user options
605
    #
606
    Error ("No package URL specified") unless ( $opt_package );
607
    Error ("No base directory specified") unless ( $opt_dir );
608
    Error ("Invalid base directory: $opt_dir") unless ( -d $opt_dir );
2424 dpurdie 609
    Error ("Cannot label if not committing") if ( $opt_label && ! $opt_commit );
311 dpurdie 610
 
611
    #
612
    #   Create an SVN session
613
    #
614
    my $svn = NewSessionByUrl ( $opt_package );
615
 
616
    #
617
    #   Ensure that the required label is available
618
    #
619
    if ( $opt_label )
620
    {
621
        $opt_label = SvnIsaSimpleLabel ($opt_label);
622
        $url_label = $svn->BranchName( $opt_label, 'tags' );
623
        $svn->SvnValidateTarget (
624
                        'target' => $url_label,
625
                        'available' => 1,
626
                        ) unless ( $opt_replace );
627
    }
628
 
629
    #
379 dpurdie 630
    #   Validate the required branch
631
    #   It will be created if it doesn't exist
632
    #
633
    if ( $opt_branch )
634
    {
635
        $opt_branch = SvnIsaSimpleLabel($opt_branch);
636
        $url_branch = $svn->BranchName( $opt_branch, 'branches' );
385 dpurdie 637
        my $rv = $svn->SvnValidateTarget (
638
                        'cmd'    => 'SvnImporter. Create branch',
379 dpurdie 639
                        'target' => $url_branch,
640
                        'create' => 1,
641
                        );
385 dpurdie 642
        if ( $rv == 2 )
643
        {
644
            $svn->setRepoProperty('svn:author', $opt_author) if (defined ($opt_author));
645
            $svn->setRepoProperty('svn:date', $opt_date) if (defined ($opt_date));
646
        }
379 dpurdie 647
    }
648
 
649
    #
311 dpurdie 650
    #   Create a workspace based on the users package
651
    #   Allow the workspace to be reused to speed up multiple
652
    #   operations
653
    #
654
    unless ( $opt_reuse && -d $opt_workdir )
655
    {
656
        Message ("Creating Workspace");
657
        rmtree( $opt_workdir );
658
 
659
        $svn->SvnValidatePackageRoot ();
660
        #DebugDumpData( 'Svn', $svn );
661
        $svn->SvnValidateTarget (
662
                            'cmd'    => 'SvnImporter',
663
                            'target' => $svn->Full,
664
                            'require' => 1,
665
                            );
666
 
379 dpurdie 667
        my $url_co = $opt_branch ? $url_branch : $svn->Full . '/trunk';
1356 dpurdie 668
        $svn->SvnCo ( $url_co, $opt_workdir, 'print' => $opt_printfiles );
311 dpurdie 669
        Error ("Cannot locate the created Workspace")
670
            unless ( -d $opt_workdir );
671
    }
672
    else
673
    {
674
        Message ("Reusing Workspace");
675
    }
2048 dpurdie 676
 
311 dpurdie 677
    #
678
    #   Determine differences between the two folders
679
    #       Create structures for each directory
680
    #
681
    Message ("Determine Files in packages");
682
 
683
    my $search = JatsLocateFiles->new("--Recurse=1",
684
                                       "--DirsToo",
685
                                       "--FilterOutRe=/\.svn/",
686
                                       "--FilterOutRe=/\.svn\$",
687
                                       "--FilterOutRe=^/${opt_workdir}\$",
688
                                       "--FilterOutRe=^/${opt_workdir}/",
689
                                       );
690
    my @ws = $search->search($opt_workdir);
691
    my @dir = $search->search($opt_dir);
692
 
1270 dpurdie 693
    #
694
    #   Scan for a source file
695
    #   Trying to detect empty views
696
    #   Look for file, not directory
2616 dpurdie 697
    #       Keep a count for reporting
1270 dpurdie 698
    #
699
    {
2616 dpurdie 700
        foreach ( @ws )
701
        {
702
            $filesBase++ unless ( m~/$~ );
703
        }
704
 
1270 dpurdie 705
        my $fileFound = 0;
706
        foreach ( @dir )
707
        {
708
            next if ( m~/$~ );
2616 dpurdie 709
            $fileFound = 1;
1270 dpurdie 710
            last;
711
        }
712
 
713
        unless ( $fileFound )
714
        {
715
            Warning ("No source files found in source view");
716
            $opr_done = 1;
717
            return;
718
        }
719
    }
720
 
311 dpurdie 721
    #Information ("WS Results", @ws);
722
    #Information ("DIR Results", @dir);
1270 dpurdie 723
    #Information ("WS Results: ", scalar @ws);
724
    #Information ("DIR Results:", scalar @dir);
311 dpurdie 725
 
726
    #
727
    #   Create a hash the Workspace and the User dir
728
    #   The key will be file names
729
    #
730
    my %ws;  map ( $ws{$_} = 1 , @ws );
731
    my %dir; map ( $dir{$_} = 1 , @dir );
732
 
733
    #
734
    #   Create a hash of common elements
735
    #   Removing then from the other two
736
    #
737
    my %common;
738
    foreach ( keys %ws )
739
    {
740
        next unless ( exists $dir{$_} );
741
        $common{$_} = 1;
742
        delete $ws{$_};
743
        delete $dir{$_};
744
    }
745
 
746
    #DebugDumpData( 'WS', \%ws );
747
    #DebugDumpData( 'DIR', \%dir );
748
    #DebugDumpData( 'COMMON', \%common );
749
 
750
    #
379 dpurdie 751
    #   Need to consider the case where a file has been replaced with a directory
752
    #   and visa-versa. Delete files and directories first.
753
    #
754
    #
755
    #   Remove files
756
    #   Sort in reverse. This will ensure that we process directory
757
    #   contents before directories
758
    #
2616 dpurdie 759
 
379 dpurdie 760
    my @rm_files = reverse sort keys %ws;
2616 dpurdie 761
    my @noDelete = split(',', $opt_nodelete);
379 dpurdie 762
    if ( @rm_files )
763
    {
2616 dpurdie 764
        my @processedFiles;
379 dpurdie 765
        foreach my $file ( @rm_files  )
766
        {
2616 dpurdie 767
            #
768
            #   Detect items that are to be retained
769
            #
770
            if ( $opt_nodelete )
771
            {
772
                my $keep = 0;
773
                foreach ( @noDelete )
774
                {
775
                    if ( $file =~ m~(^|/)$_(/|$)~ )
776
                    {
777
#                        Verbose0("Not deleting: $file");
778
                        $keep = 1;
779
                        last;
780
                    }
781
                }
782
                next if ($keep);
783
            }
784
 
379 dpurdie 785
            Verbose ("Removing $file");
2616 dpurdie 786
            $filesDeleted++ unless ( $file =~ m~/$~ );
787
            $dirsDeleted++ if ( $file =~ m~/$~ );
379 dpurdie 788
            unlink "$opt_workdir/$file";
2616 dpurdie 789
            push @processedFiles, $file;
379 dpurdie 790
        }
2616 dpurdie 791
        @rm_files = @processedFiles;
379 dpurdie 792
 
793
        #
794
        #   Inform Subversion about the removed files
795
        #
796
        my $base = 0;
797
        my $num = $#rm_files;
2616 dpurdie 798
        Message ("Update the workspace: Removed $filesDeleted Files, $dirsDeleted directories");
379 dpurdie 799
 
800
        while ( $base <= $num )
801
        {
802
            my $end = $base + 200;
803
            $end = $num if ( $end > $num );
804
 
805
            $svn->SvnCmd ( 'delete', map ("$opt_workdir/$_@", @rm_files[$base .. $end] ),
806
                            { 'error' => 'Deleting files from workspace' } );
2048 dpurdie 807
 
379 dpurdie 808
            $base = $end + 1;
809
        }
810
    }
2048 dpurdie 811
 
379 dpurdie 812
    #
311 dpurdie 813
    #   Add New Files
814
    #   Won't add empty directories at this point
815
    #
816
    #   Process by sorted list
817
    #   This will ensure we process parent directories first
818
    #
819
    my @added = sort keys %dir;
820
    if ( @added )
821
    {
822
        foreach my $file ( @added  )
823
        {
824
            my $src = "$opt_dir/$file";
825
            my $target = "$opt_workdir/$file";
2616 dpurdie 826
            $filesAdded++ unless ( $file =~ m~/$~ );
827
            $dirsAdded++ if ( $file =~ m~/$~ );
311 dpurdie 828
 
829
            if ( -d $src )
830
            {
379 dpurdie 831
                Verbose ("Adding directory: $file");
311 dpurdie 832
                mkdir ( $target ) unless (-d $target);
833
            }
834
            else
835
            {
836
 
837
                my $path = dirname ( $target);
838
                mkdir ( $path ) unless (-d $path);
839
 
840
                Verbose ("Adding $file");
841
                unless (File::Copy::copy( $src, $target ))
842
                {
843
                    Error("Failed to transfer file [$file]: $!");
844
                }
845
            }
846
        }
847
 
848
        #
849
        #   Inform Subversion about the added files
850
        #   The command line does have a finite length, so add them 200 at a
851
        #   time.
852
        #
853
 
854
        my $base = 0;
855
        my $num = $#added;
2616 dpurdie 856
        Message ("Update the workspace: Added $filesAdded Files, $dirsAdded directories");
311 dpurdie 857
 
858
        while ( $base <= $num )
859
        {
860
            my $end = $base + 200;
861
            $end = $num if ( $end > $num );
862
 
863
            $svn->SvnCmd ( 'add'
864
                            , '--depth=empty'
865
                            , '--parents'
379 dpurdie 866
                            , map ("$opt_workdir/$_@", @added[$base .. $end] ),
311 dpurdie 867
                            { 'error' => 'Adding files to workspace' } );
868
 
869
            $base = $end + 1;
870
        }
871
    }
872
 
873
    #
874
    #   The common files may have changed
875
    #   Simply copy them all in and let subversion figure it out
876
    #
877
    foreach my $file ( sort keys %common  )
878
    {
879
        my $src = "$opt_dir/$file";
880
        my $target = "$opt_workdir/$file";
881
 
882
        next if ( -d $src );
883
        if ( File::Compare::compare ($src, $target) )
884
        {
885
            Verbose ("Transfer $file");
886
            unlink $target;
887
            unless (File::Copy::copy( $src, $target ))
888
            {
889
                Error("Failed to transfer file [$file]: $!",
890
                      "Src: $src",
891
                      "Tgt: $target");
892
            }
893
        }
894
    }
895
 
896
    #
897
    #   Commit the workspace
898
    #   This will go back onto the trunk
899
    #
2424 dpurdie 900
    if ( $opt_commit )
901
    {
902
        $svn = NewSessionByWS( $opt_workdir );
903
        my $pkgPath = $svn->Path();
387 dpurdie 904
 
2424 dpurdie 905
        my $ciComment = "$pkgPath: Checkin by Svn Import";
906
        $ciComment .= "\n" . $opt_log if ( $opt_log );
907
        $ciComment =~ s~\r\n~\n~g;
908
        $ciComment =~ s~\r~\n~g;
909
        $ciComment = encode('UTF-8', $ciComment, Encode::FB_DEFAULT);
387 dpurdie 910
 
2424 dpurdie 911
        $svn->SvnCi ('comment' => $ciComment, 'allowSame' => 1 );
912
        Message ("Repository Ref: " . $svn->RmRef) unless( $opt_label );
379 dpurdie 913
        $svn->setRepoProperty('svn:author', $opt_author) if (defined ($opt_author));
914
        $svn->setRepoProperty('svn:date', $opt_date) if (defined ($opt_date));
2424 dpurdie 915
 
916
        #
917
        #   Label the result
918
        #   The workspace will have been updated, so we can use it as the base for
919
        #   the labeling process
920
        #
921
        if ( $opt_label )
922
        {
923
            $svn->SvnCopyWs (
924
                           target => $url_label,
925
                           'noswitch' => 1,
926
                           'replace' => $opt_replace,
927
                           'comment' => "$pkgPath: Tagged by Jats Svn Import",
928
                           );
929
            Message ("Repository Ref: " . $svn->RmRef);
930
            Message ("Vcs Tag       : " . $svn->SvnTag);
931
            $svn->setRepoProperty('svn:author', $opt_author) if (defined ($opt_author));
932
            $svn->setRepoProperty('svn:date', $opt_date) if (defined ($opt_date));
933
        }
311 dpurdie 934
    }
2424 dpurdie 935
    else
936
    {
937
        Message ("Workspace not commited","Workspace: $opt_workdir");
938
    }
311 dpurdie 939
 
940
    #
941
    #   Clean up
942
    #
2424 dpurdie 943
    if ( $opt_delete && ! $opt_reuse  && $opt_commit )
311 dpurdie 944
    {
945
        Message ("Delete Workspace");
946
        rmtree( $opt_workdir );
947
    }
379 dpurdie 948
 
949
    #
950
    #   Automation data transfer
951
    #
952
    if ( defined $opt_datafile )
953
    {
954
        my $data = JatsProperties::New();
955
 
956
        $data->setProperty('Command'        , 'ImportPackage');
957
        $data->setProperty('Label'          , $opt_label);
1347 dpurdie 958
        $data->setProperty('subversion.url' , $svn->RmRef);
959
        $data->setProperty('subversion.tag' , $svn->SvnTag);
379 dpurdie 960
 
2616 dpurdie 961
        $data->setProperty('files.base'     , $filesBase);
962
        $data->setProperty('files.removed'  , $filesDeleted);
963
        $data->setProperty('files.added'    , $filesAdded);
964
 
379 dpurdie 965
        $data->Dump('InfoFile') if ($opt_verbose);
966
        $data->store( $opt_datafile );
967
    }
968
 
311 dpurdie 969
    $opr_done = 1;
970
}
971
 
972
#-------------------------------------------------------------------------------
385 dpurdie 973
# Function        : DeleteBranch
974
#
975
# Description     : Delete the branch that a workspace is based upon
976
#
2048 dpurdie 977
# Inputs          :
385 dpurdie 978
#
2048 dpurdie 979
# Returns         :
385 dpurdie 980
#
981
sub DeleteBranch
982
{
983
    my $opt_path;
984
    my $opt_error = 0;
985
    #
986
    #   Parse more options
987
    #
988
    GetOptions (
989
                "help:+"        => \$opt_help,
990
                "manual:3"      => \$opt_help,
991
                "path:s"        => \$opt_path,
992
                ) || Error ("Invalid command line" );
993
 
994
    #
995
    #   Subcommand specific help
996
    #
997
    SubCommandHelp( $opt_help, "Delete Branch") if ($opt_help);
998
 
999
    #
1000
    #   Sanity Tests
1001
    #
2071 dpurdie 1002
    Message ("Delete Workspace Branchs" );
385 dpurdie 1003
 
1004
    #
1005
    #   Do all the hard work
1006
    #
1007
    $opt_path = '.' unless ( defined $opt_path );
1008
    my $uref = NewSessionByWS($opt_path, 0, 1);
1009
    my $ws_root = $uref->SvnLocateWsRoot(1);
1010
    my $ws_url = $uref->FullWs();
1011
 
1012
    #
2071 dpurdie 1013
    #   What we do depends what aruments the user provided
385 dpurdie 1014
    #
2071 dpurdie 1015
    unless ( @ARGV )
1016
    {
1017
        #
1018
        #   If no branch was specified - then display the workspace branch
1019
        #
1020
        Error ('The workspace is not based on a branch')
1021
            unless ( $ws_url =~ m ~/branches/(.*)~ );
1022
        Message('The workspace is based on the branch: '. $1);
1023
    }
1024
    else
1025
    {
1026
        #
1027
        #   Delete all specified branches
1028
        #
1029
        foreach my $branch ( @ARGV )
1030
        {
1031
            Message ("Deleting: " . $branch );
1032
            my $target = join( '/', $uref->FullPath(), 'branches', $branch);
1033
            if ( $uref->SvnDelete (
1034
                              'target'    => $target,
1035
                              'comment'   => [$uref->Path().": Delete Branch",'Deleted by user command: jats svn delete-branch'],
1036
                              'noerror'   => 1,
1037
                              )
1038
               )
1039
            {
1040
                Warning ("Branch deletion failed: $branch");
1041
            }
1042
        }
1043
    }
385 dpurdie 1044
    $opr_done = 1;
1045
}
1046
 
2048 dpurdie 1047
#-------------------------------------------------------------------------------
1048
# Function        : CreateBranch
1049
#
1050
# Description     : Branch a workspace and then switch to the new branch
1051
#
1052
# Inputs          :
1053
#
1054
# Returns         :
1055
#
1056
sub CreateBranch
1057
{
1058
    my $opt_path;
1059
    my $opt_comment;
1060
    my $opt_switch = 1;
1061
    my $opt_branch;
385 dpurdie 1062
 
2048 dpurdie 1063
    #
1064
    #   Parse more options
1065
    #
1066
    GetOptions (
1067
                "help:+"        => \$opt_help,
1068
                "manual:3"      => \$opt_help,
1069
                "path:s"        => \$opt_path,
1070
                "switch!"       => \$opt_switch,
1071
                "comment:s"     => \$opt_comment,
1072
                ) || Error ("Invalid command line" );
1073
 
1074
    #
1075
    #   Subcommand specific help
1076
    #
1077
    SubCommandHelp( $opt_help, "Create Branch") if ($opt_help);
1078
 
1079
    #
1080
    #   Sanity Tests
1081
    #
1082
    Message ("Create Workspace Branch" );
1083
    Error ("Too many arguments: @ARGV") if ( $#ARGV > 0 );
1084
    Error ("Not enough arguments. No branch name specified") if ( $#ARGV < 0 );
1085
 
1086
    #
1087
    #   Sanity test the label
1088
    #
1089
    $opt_branch = SvnIsaSimpleLabel ($ARGV[0] );
1090
 
1091
    #
1092
    #   Do all the hard work
1093
    #
1094
    $opt_path = '.' unless ( defined $opt_path );
1095
    my $uref = NewSessionByWS($opt_path, 0, 1);
1096
    my $ws_root = $uref->SvnLocateWsRoot(1);
1097
    my $ws_url = $uref->Full();
1098
 
1099
    #
1100
    #   Use the verion of the branch that has been committed as the base of the
1101
    #   copy. If the user has modified files, then they won't be commited
1102
    #
1103
    #   This operation will be server-side only
1104
    #
1105
    Message ("Creating branch: $opt_branch");
1106
    my $repoLink = $uref->{InfoWs}{URL} . '@' . $uref->{InfoWs}{Revision};
1107
    $uref->{DEVBRANCH} =  join ('/', 'branches', $opt_branch);
1108
    my $branch_tag = $uref->SvnCopy (
1109
                'old' => $repoLink,
1110
                'new' => join ('/', $ws_url, $uref->{DEVBRANCH} ),
1111
                'comment' => $opt_comment ? $opt_comment : 'Created by Jats svn branch',
1112
                'replace' => 0,
1113
                );
1114
 
2053 dpurdie 1115
 
2048 dpurdie 1116
    if ( $opt_switch )
1117
    {
1118
        Verbose ("Switching to new branch: $opt_branch");
1119
        $branch_tag = SvnPath2Url($branch_tag);
2053 dpurdie 1120
        chdir ($ws_root) || Error ("Cannot cd to: " .$ws_root);
1121
        $uref->SvnSwitch ($branch_tag, $opt_path, '--Print', '--KeepWs' );
2048 dpurdie 1122
    }
1123
    else
1124
    {
1125
        Warning ("Using existing workspace, not the created branch");
1126
    }
1127
    Message ("Repository Ref: " . $uref->RmRef);
1128
    Message ("Vcs Tag       : " . $uref->SvnTag);
1129
 
1130
#    #
1131
#    #   The copy operation *should* be a server side operation only
1132
#    #   If the user has commited changes, but not yet updated the local
1133
#    #   workspace, then subversion will do a client side copy
1134
#    #   This is not good.
1135
#    #
1136
#    $uref->SvnCopyWs (
1137
#                   target => join ('/', $ws_url, 'branches', $opt_branch),
1138
#                   'allowLocalMods' => 1,
1139
#                   'noupdatecheck' => 1,
1140
#                   'noswitch' => ! $opt_switch,
1141
#                   'replace' => 0,
1142
#                   'comment' => $opt_comment ? $opt_comment : 'Created by Jats svn branch',
1143
#                   );
1144
#
1145
#    Message ("Repository Ref: " . $uref->RmRef);
1146
#    Message ("Vcs Tag       : " . $uref->SvnTag);
1147
 
1148
    $opr_done = 1;
1149
}
1150
 
385 dpurdie 1151
#-------------------------------------------------------------------------------
2048 dpurdie 1152
# Function        : SwitchBranch
1153
#
1154
# Description     : Switch to a specified branch
1155
#
1156
# Inputs          :
1157
#
1158
# Returns         :
1159
#
1160
sub SwitchBranch
1161
{
1162
    my $opt_path = '.';
1163
    my $opt_branch;
1164
 
1165
    #
1166
    #   Parse more options
1167
    #
1168
    GetOptions (
1169
                "help:+"        => \$opt_help,
1170
                "manual:3"      => \$opt_help,
1171
                "path:s"        => \$opt_path,
1172
                ) || Error ("Invalid command line" );
1173
 
1174
    #
1175
    #   Subcommand specific help
1176
    #
1177
    SubCommandHelp( $opt_help, "Switch Branch") if ($opt_help);
1178
    return ShowBranches($opt_path) if ( $#ARGV < 0 );
1179
 
1180
    #
1181
    #   Sanity Tests
1182
    #
1183
    Error ("Too many arguments: @ARGV") if ( $#ARGV > 0 );
1184
 
1185
    #
1186
    #   Calculate the target name
1187
    #       trunk is special
1188
    #       tags/... is special
1189
    $opt_branch = $ARGV[0];
1190
    if ( $opt_branch eq 'trunk' ) {
1191
    } elsif ( $opt_branch =~ m~tags/.+~ ) {
1192
    } else {
1193
        $opt_branch = join ('/', 'branches', $opt_branch);
1194
    }
1195
    Message ("Switching to new branch: $opt_branch");
1196
 
1197
    #
1198
    #   Do all the hard work
1199
    #
1200
    my $uref = NewSessionByWS($opt_path, 0, 1);
2053 dpurdie 1201
    my $ws_root = $uref->SvnLocateWsRoot(1);
2048 dpurdie 1202
    my $ws_url = $uref->Full();
1203
    my $branch_tag = join ('/', $ws_url, $opt_branch);
1204
 
1205
    #
1206
    #   Validate the branch
1207
    #
1208
    $uref->SvnValidateTarget (
1209
                        'cmd'    => 'svn switch',
1210
                        'target' => $branch_tag,
1211
                        'require' => 1,
1212
                        );
1213
 
2053 dpurdie 1214
    #
1215
    #   Must Change directory before we switch
1216
    #   Otherwise we will import chnages into the wrong place
1217
    #
1218
    chdir ($ws_root) || Error ("Cannot cd to: " . $ws_root);
1219
    $uref->SvnSwitch ($branch_tag, $opt_path, '--Print', '--KeepWs' );
2048 dpurdie 1220
    $opr_done = 1;
1221
}
1222
 
1223
#-------------------------------------------------------------------------------
1224
# Function        : ShowBranches
1225
#
1226
# Description     : Show branches in current workspace
1227
#                   Internal use only
1228
#
1229
# Inputs          : $opt_path           - Optional path
1230
#
1231
# Returns         :
1232
#
1233
sub ShowBranches
1234
{
1235
    my ($opt_path) = @_;
1236
 
1237
    my $uref = NewSessionByWS($opt_path, 0, 1);
1238
    my $ws_url = $uref->Full();
1239
 
1240
    #
1241
    #   Display the packages full URL - allow the user to manuallu look at more
1242
    #   List the bracnhes
1243
    #
1244
    Message ("Url: $ws_url", 'Available Branches');
1245
    SvnUserCmd( 'ls', join ('/', $ws_url, 'branches'), { 'credentials' => 1 });
1246
    $opr_done = 1;
1247
}
1248
#-------------------------------------------------------------------------------
311 dpurdie 1249
# Function        : SubCommandHelp
1250
#
1251
# Description     : Provide help on a subcommand
1252
#
1253
# Inputs          : $help_level             - Help Level 1,2,3
1254
#                   $topic                  - Topic Name
1255
#
1256
# Returns         : This function does not return
1257
#
1258
sub SubCommandHelp
1259
{
1260
    my ($help_level, $topic) = @_;
1261
    my @sections;
1262
    #
1263
    #   Spell out the section we want to display
1264
    #
1265
    #   Note:
1266
    #   Due to bug in pod2usage can't use 'head1' by itself
1267
    #   Each one needs a subsection.
1268
    #
1269
    push @sections, qw( NAME SYNOPSIS ) ;
1270
    push @sections, qw( ARGUMENTS OPTIONS ) if ( $help_level > 1 );
1271
    push @sections, qw( DESCRIPTION )       if ( $help_level > 2 );
1272
 
1273
    #
1274
    #   Extract section from the POD
1275
    #
1276
    pod2usage({-verbose => 99,
1277
               -noperldoc => 1,
1278
               -sections => $topic . '/' . join('|', @sections) } );
1279
}
1280
 
1281
#-------------------------------------------------------------------------------
1282
#   Documentation
1283
#   NOTE
1284
#
1285
#   Each subcommand MUST have
1286
#   head1 section as used by the subcommand
1287
#       This should be empty, as the contents will NOT be displayed
1288
#   head2 sections called
1289
#       NAME SYNOPSIS ARGUMENTS OPTIONS DESCRIPTION
1290
#
1291
#=head1 xxxxxx
1292
#=head2 NAME
1293
#=head2 SYNOPSIS
1294
#=head2 ARGUMENTS
1295
#=head2 OPTIONS
1296
#=head2 DESCRIPTION
1297
#
1298
 
1299
=pod
1300
 
361 dpurdie 1301
=for htmltoc    GENERAL::Subversion::
1302
 
311 dpurdie 1303
=head1 NAME
1304
 
1305
jats svn - Miscellaneous SubVersion Operations
1306
 
1307
=head1 SYNOPSIS
1308
 
1309
jats svn [options] command [command options]
1310
 
1311
 Options:
1312
    -help[=n]              - Help message, [n=1,2,3]
1313
    -man                   - Full documentation [-help=3]
1314
    -verbose[=n]           - Verbose command operation
1315
 
1316
 Common Command Options:
1317
    All command support suboptions to provide command specific help
1318
 
1319
    -help[=n]              - Help message, [n=1,2,3]
1320
    -man                   - Full documentation [-help=3]
1321
 
1322
 Commands are:
363 dpurdie 1323
    test                   - Test access to subversion
369 dpurdie 1324
    paths                  - Display Subversion tag to URL conversions
311 dpurdie 1325
    ls URL                 - List Repo contents for URL
369 dpurdie 1326
    tag [URL]              - Convert URL or Path to a Release Manager Tag
1327
    url [TAG]              - Convert TAG or Path to a Subversion URL
2048 dpurdie 1328
    create-package URL     - Create a new package at URL
311 dpurdie 1329
    delete-package URL     - Delete Package Subtree
2048 dpurdie 1330
    branch BRANCH          - Create a Development Branch
1331
    switch [BRANCH]        - Switch to a Development Branch
385 dpurdie 1332
    delete-branch          - Delete a Development Branch
311 dpurdie 1333
    import URL             - Import files to package at URL
1334
 
1335
 Use the command
1336
    jats svn command -h
1337
 for command specific help
1338
 
1339
=head1 OPTIONS
1340
 
1341
=over
1342
 
1343
=item B<-help[=n]>
1344
 
1345
Print a help message and exit. The level of help may be either 1, 2 or
1346
3 for a full manual.
1347
 
1348
This option may be specified multiple times to increment the help level, or
1349
the help level may be directly specified as a number.
1350
 
1351
=item B<-man>
1352
 
1353
This is the same as '-help=3'.
1354
The complete help is produced in a man page format.
1355
 
2071 dpurdie 1356
=item B<-verbose[=n]>
311 dpurdie 1357
 
1358
This option will increase the level of verbosity of the commands.
1359
 
1360
If an argument is provided, then it will be used to set the level, otherwise the
1361
existing level will be incremented. This option may be specified multiple times.
1362
 
1363
=back
1364
 
1365
=head1 DESCRIPTION
1366
 
1367
This program provides a number of useful Subversion based operations.
1368
 
363 dpurdie 1369
=head1 Test Subversion
1370
 
1371
=head2 NAME
1372
 
1373
Test Subversion
1374
 
1375
=head2 SYNOPSIS
1376
 
1377
    jats svn test
1378
 
1379
=head2 DESCRIPTION
1380
 
1381
This command will ensure that the subversion command line utility can be
1382
located. The command will report the version of the svn client found.
1383
 
369 dpurdie 1384
=head1 Subversion Paths
1385
 
1386
=head2 NAME
1387
 
1388
Subversion Paths
1389
 
1390
=head2 SYNOPSIS
1391
 
1392
    jats svn paths
1393
 
1394
=head2 DESCRIPTION
1395
 
1396
This command will display the base Tags and associated URLs that are used by
1397
JATS to convert a 'Subversion Tag' into a full URLs that will be used to access
1398
a physical repository.
1399
 
1400
The 'Tags' configuration is site-specific.
1401
 
311 dpurdie 1402
=head1 List Repository
1403
 
363 dpurdie 1404
=head2 NAME
1405
 
1406
List Repository
1407
 
1408
=head2 SYNOPSIS
1409
 
1410
    jats svn ls <URL>
1411
 
1412
=head2 DESCRIPTION
1413
 
311 dpurdie 1414
This command will take a URL and perform a 'svn' list operation. The URL will
1415
be expanded to include the site specific repository.
1416
 
369 dpurdie 1417
=head1 Url to Tag
1418
 
1419
=head2 NAME
1420
 
1421
Url to Tag
1422
 
1423
=head2 SYNOPSIS
1424
 
1425
    jats svn tag [Option] [tag]
1426
 
1427
 Options:
1428
    -help[=n]              - Help message, [n=1,2,3]
1429
    -man                   - Full documentation [-help=3]
1430
    -path=path             - Convert specified path
1431
    -url=url               - Convert specified URL
1432
 
1433
=head2 DESCRIPTION
1434
 
1435
This command will convert a URL or a PATH to a Subversion Tag that can
1436
be used within the remainder of the build system. If no PATH or URL is provided,
1437
then the command uses a path of the current directory.
1438
 
1439
The command will convert either a PATH or a URL. It will not do both.
1440
 
1441
The command will use the configured Subversion URL prefixes to create the Tag.
1442
 
1443
If a PATH is to be converted, then the PATH must address a Subversion workspace.
1444
The conversion will return a Tag to the root of the Workspace and Peg it to
1445
the last committed version. The command will not determine if the workspace
1446
contains modified files.
1447
 
1448
If a URL is to be converted, then the resultant value should be used with
1449
caution. The result is only as good as the provided URL and may not address
1450
the root of a package.
1451
 
1452
=head1 Tag to Url
1453
 
1454
=head2 NAME
1455
 
1456
Tag to Url
1457
 
1458
=head2 SYNOPSIS
1459
 
1460
    jats svn url [Option] [url]
1461
 
1462
 Options:
1463
    -help[=n]              - Help message, [n=1,2,3]
1464
    -man                   - Full documentation [-help=3]
1465
    -path=path             - Convert specified path
1466
    -url=url               - Convert specified URL
1467
 
1468
=head2 DESCRIPTION
1469
 
1470
This command will convert a TAG or a PATH to a full URL that can be used
1471
directly by Subversion. If no PATH or TAG is provided, then the command uses a
1472
path of the current directory.
1473
 
2424 dpurdie 1474
The command will convert either a TAG or a PATH. It will not do both.
369 dpurdie 1475
 
1476
The command will use the configured Subversion URL prefixes to expand the TAG.
1477
 
1478
If a PATH is to be converted, then the PATH must address a Subversion workspace.
1479
The conversion will return a URL to the root of the Workspace and Peg it to
1480
the last committed version. The command will not determine if the workspace
1481
contains modified files.
1482
 
1483
If a TAG is to be converted, then the resultant value should be used with
1484
caution. The result is only as good as the provided URL and may not address
1485
the root of a package.
1486
 
2424 dpurdie 1487
=head3 Examples
1488
 
1489
To display the URL of the current workspace
1490
 
1491
    jats svn url
1492
 
1493
To display the URL of a known workspace
1494
 
1495
    jats svn url -path=myWorkSpace
1496
 
1497
To convert a TAG from Release Manager or other JATS commands
1498
 
1499
    jats svn url AUPERASVN01/COTS
1500
    jats svn url SVN::AUPERASVN01/COTS/bouncycastle/trunk::bouncycastle_1.3.1.cots@502
1501
 
2048 dpurdie 1502
=head1 Create a Package Version
1503
 
1504
=head2 NAME
1505
 
1506
Create a Package Version
1507
 
1508
=head2 SYNOPSIS
1509
 
1510
jats svn [options] create-package URL [command options]
1511
 
1512
 Options:
1513
    -help[=n]               - Help message, [n=1,2,3]
1514
    -man                    - Full documentation [-help=3]
1515
    -verbose[=n]            - Verbose command operation
1516
 
1517
 Command Options
1518
    -help[=n]               - Provide command specific help
1519
    -new                    - Package must not exist
1520
    -replace                - Replace any existing versions
2354 dpurdie 1521
    -import=path            - Import directory tree
2048 dpurdie 1522
    -label=nnn              - Label imported package
1523
    -trunk                  - Import to trunk (default)
1524
    -tags=nnn               - Import to tags
1525
    -branch=nnn             - Import to branches
1526
 
1527
=head2 ARGUMENTS
1528
 
1529
The command takes one argument: The URL of the desired package.
1530
This may be be:
1531
 
1532
=over
1533
 
1534
=item * A full URL
1535
 
1536
Complete with protocol and path information.
1537
 
1538
=item * A simple URL
1539
 
1540
JATS will prepend the site-specific repository location to the user provided URL
1541
 
1542
=back
1543
 
1544
=head2 OPTIONS
1545
 
1546
=over
1547
 
1548
=item -help[=n]
1549
 
1550
Print a help message and exit. The level of help may be either 1, 2 or 3.
1551
 
1552
This option may be specified multiple times to increment the help level, or
1553
the help level may be directly specified as a number.
1554
 
1555
=item -new
1556
 
1557
This option specifies that the named package MUST not exist at all.
1558
 
1559
=item -replace
1560
 
1561
This option allows the program to replace any existing versions of the
1562
imported source. It will allow the deletion of any existing trunk, tags or
1563
branches.
1564
 
2354 dpurdie 1565
=item -import=path
2048 dpurdie 1566
 
1567
This option specifies the path of a subdirectory tree to import into the newly
1568
created package. In not provided, then only a package skeleton will be created.
1569
 
2354 dpurdie 1570
All files and directories below, but not including, the named path will be
1571
imported into the package.
1572
 
2048 dpurdie 1573
=item -label=nnn
1574
 
1575
This option specifies a label to place the imported source.
1576
 
1577
=item -trunk
1578
 
1579
This option specifies that imported source will be placed on the trunk of the
1580
package. This is the default mode of import.
1581
 
1582
The options -trunk, -tags and -branch are mutually exclusive.
1583
 
1584
=item -tags=nnn
1585
 
1586
This option specifies that imported source will be placed directly on the
1587
named tag of the package.
1588
 
1589
The options -trunk, -tags and -branch are mutually exclusive.
1590
 
1591
=item -branch=nnn
1592
 
1593
This option specifies that imported source will be placed directly on the
1594
named branch of the package.
1595
 
1596
The options -trunk, -tags and -branch are mutually exclusive.
1597
 
1598
=back
1599
 
1600
=head2 DESCRIPTION
1601
 
1602
This command will create a new package within a repository. It will ensure
1603
that the package contains the three required subdirectories: trunk, tags and
1604
branches.
1605
 
1606
The command will also ensure that packages are not placed at inappropriate
1607
locations within the repository. It is not correct to place a package within
1608
another package.
1609
 
1610
The command will, optionally, import a directory tree into the repository and,
1611
optionally, label the package.
1612
 
1613
The package body may be imported to the 'trunk' or to a branch or a tag.
1614
By default the data will be imported to the trunk and may be labeled (tagged).
1615
 
1616
Options allow the targets to be deleted if they exist or to ensure that they
1617
are not present.
1618
 
1619
The command does not attempt to merge file versions within the repository. It
1620
may result in multiple instances of a file within the repository. Use only for
1621
simple imports. Use the 'import' command for more sophisticated import requirements.
1622
 
2354 dpurdie 1623
=head3 Examples
1624
 
1625
To create a package skeleton in the Perth MREF_Package repository for a package
1626
called 'VIXmyPackage':
1627
 
1628
    jats svn create-package AUPERASVN01/MREF_Package/VIXmyPackage
1629
 
1630
To create a package skeleton in the Perth MREF_Package repository, import code
1631
into the trunk of the package and label (tag) it:
1632
 
1633
    jats svn create-package \
1634
           AUPERASVN01/MREF_Package/VIXmyPackage \
1635
           -import=VIXmyNewPackage \
1636
           -label=VIXmyPackage.WIP
1637
 
311 dpurdie 1638
=head1 Delete a Package
1639
 
1640
=head2 NAME
1641
 
1642
Delete a Package
1643
 
1644
=head2 SYNOPSIS
1645
 
1646
jats svn delete-package URL [options]
1647
 
1648
 Options:
1649
    -help[=n]              - Help message, [n=1,2,3]
1650
    -man                   - Full documentation [-help=3]
1651
    -verbose[=n]           - Verbose command operation
1652
 
1653
=head2 ARGUMENTS
1654
 
1655
The command takes one argument: The URL of the desired package.
1656
This may be be:
1657
 
1658
=over
1659
 
1660
=item * A full URL
1661
 
1662
Complete with protocol and path information.
1663
 
1664
=item * A simple URL
1665
 
1666
JATS will prepend the site-specific repository location to the user provided URL
1667
 
1668
=back
1669
 
1670
=head2 OPTIONS
1671
 
1672
This command has no significant options, other than the general help options.
1673
 
1674
=head2 DESCRIPTION
1675
 
1676
This command will delete a package from the repository. It will ensure
1677
that the package is a valid package, before it is deleted.
1678
 
1679
The command is intended to be used by test scripts, rather than users.
1680
 
2048 dpurdie 1681
=head1 Create Branch
385 dpurdie 1682
 
1683
=head2 NAME
1684
 
2048 dpurdie 1685
Create a Workspace Branch
385 dpurdie 1686
 
1687
=head2 SYNOPSIS
1688
 
2048 dpurdie 1689
jats svn branch branch-name [options]
385 dpurdie 1690
 
1691
 Options:
1692
    -help[=n]              - Help message, [n=1,2,3]
1693
    -man                   - Full documentation [-help=3]
1694
    -verbose[=n]           - Verbose command operation
1695
    -path=path             - Target workspace
2048 dpurdie 1696
    -[no]switch            - Switch to new branch(default)
1697
    -comment=text          - Comment to apply to the new branch
385 dpurdie 1698
 
1699
=head2 ARGUMENTS
1700
 
2048 dpurdie 1701
The command takes one argument. The name of the branch to be created.
385 dpurdie 1702
 
1703
=head2 OPTIONS
1704
 
1705
=over
1706
 
1707
=item B<-path=path>
1708
 
1709
This options specifies the path of the target workspace. If not provided the
1710
command will use the current directory.
1711
 
2048 dpurdie 1712
=item B<-[no]switch>
1713
 
1714
If enabled (the default) the workspace will be switched to the new branch at
1715
the end of the process.
1716
 
1717
=item B<-comment=text>
1718
 
1719
If present, the specified text will be used as a Subversion comment when the
1720
branch is created.
1721
 
1722
If not provided, then JATS will provide a basic comment.
1723
 
385 dpurdie 1724
=back
1725
 
1726
=head2 DESCRIPTION
1727
 
2048 dpurdie 1728
This command will create a named branch associated with the workspace in the
1729
specified path. It is intended to simplify the creation of Private or
385 dpurdie 1730
Development branches.
1731
 
2048 dpurdie 1732
If the named branch already exists, then the command will fail.
385 dpurdie 1733
 
2048 dpurdie 1734
The command performs a server-side copy. It will not commit any locally
1735
modified files. Nor will it inform you if there are any.
311 dpurdie 1736
 
2048 dpurdie 1737
By default, the user is 'switched' to the newly created branch.
1738
 
1739
=head1 Switch Branch
1740
 
311 dpurdie 1741
=head2 NAME
1742
 
2048 dpurdie 1743
Switch a Workspace Branch
311 dpurdie 1744
 
1745
=head2 SYNOPSIS
1746
 
2048 dpurdie 1747
jats svn switch [branch-name] [options]
311 dpurdie 1748
 
1749
 Options:
2048 dpurdie 1750
    -help[=n]              - Help message, [n=1,2,3]
1751
    -man                   - Full documentation [-help=3]
1752
    -verbose[=n]           - Verbose command operation
1753
    -path=path             - Target workspace
311 dpurdie 1754
 
1755
=head2 ARGUMENTS
1756
 
2048 dpurdie 1757
The command takes one optional argument. The name of the target branch.
311 dpurdie 1758
 
2048 dpurdie 1759
=head2 OPTIONS
1760
 
311 dpurdie 1761
=over
1762
 
2048 dpurdie 1763
=item B<-path=path>
311 dpurdie 1764
 
2048 dpurdie 1765
This options specifies the path of the target workspace. If not provided the
1766
command will use the current directory.
311 dpurdie 1767
 
2048 dpurdie 1768
=back
311 dpurdie 1769
 
2048 dpurdie 1770
=head2 DESCRIPTION
311 dpurdie 1771
 
2048 dpurdie 1772
This command will switch the users workspace to the named branch. This is
1773
identical to the Subversion switch command, except it is easier to user and
1774
has several validity checks and other enhancements.
311 dpurdie 1775
 
2048 dpurdie 1776
The command has two modes of operation:
311 dpurdie 1777
 
2048 dpurdie 1778
=over 4
311 dpurdie 1779
 
2048 dpurdie 1780
=item   1. Display a list of branched in the current package.
311 dpurdie 1781
 
2048 dpurdie 1782
If no branch is specified, then the utility will display a list of branches in
1783
the packages 'branches' directory.
311 dpurdie 1784
 
2048 dpurdie 1785
=item   2. Switch to the named branch.
311 dpurdie 1786
 
2048 dpurdie 1787
The named branch must exists otherwise the command will fail.
311 dpurdie 1788
 
2354 dpurdie 1789
There are two special variants of the branch name:
311 dpurdie 1790
 
2048 dpurdie 1791
=over 4
311 dpurdie 1792
 
2048 dpurdie 1793
=item trunk
311 dpurdie 1794
 
2048 dpurdie 1795
If the branch is named 'trunk' then it will refer to the packages truck
1356 dpurdie 1796
 
2048 dpurdie 1797
=item tags
1356 dpurdie 1798
 
2048 dpurdie 1799
If the branch name starts with 'tags/', then the command will refer to
1800
a tag within the package and not a branch.
1356 dpurdie 1801
 
2048 dpurdie 1802
=back
1356 dpurdie 1803
 
2048 dpurdie 1804
The command will add and remove unmodified files from the workspace during this
1805
operation.
311 dpurdie 1806
 
2048 dpurdie 1807
=back
311 dpurdie 1808
 
2048 dpurdie 1809
=head3 Examples
311 dpurdie 1810
 
2048 dpurdie 1811
To switch to the packages trunk
311 dpurdie 1812
 
2048 dpurdie 1813
    jats svn switch trunk
311 dpurdie 1814
 
2048 dpurdie 1815
To switch to the a branch called MyBranch
311 dpurdie 1816
 
2048 dpurdie 1817
    jats svn switch MyBranch
311 dpurdie 1818
 
2048 dpurdie 1819
To switch to a tagged version of the package
311 dpurdie 1820
 
2048 dpurdie 1821
    jats svn switch tags/MyPackage_1.0.0000.cr
311 dpurdie 1822
 
2048 dpurdie 1823
To display a list of available branches (not tags)
311 dpurdie 1824
 
2048 dpurdie 1825
    jats svn switch
311 dpurdie 1826
 
2048 dpurdie 1827
=head1 Delete Branch
311 dpurdie 1828
 
2048 dpurdie 1829
=head2 NAME
311 dpurdie 1830
 
2048 dpurdie 1831
Delete the Workspace Branch
311 dpurdie 1832
 
2048 dpurdie 1833
=head2 SYNOPSIS
311 dpurdie 1834
 
2071 dpurdie 1835
jats svn delete-branch [options] [branch-list]
311 dpurdie 1836
 
2048 dpurdie 1837
 Options:
1838
    -help[=n]              - Help message, [n=1,2,3]
1839
    -man                   - Full documentation [-help=3]
1840
    -verbose[=n]           - Verbose command operation
1841
    -path=path             - Target workspace
311 dpurdie 1842
 
2048 dpurdie 1843
=head2 ARGUMENTS
1844
 
2354 dpurdie 1845
The command may take zero or more arguments. If provided the arguments will be
2071 dpurdie 1846
branch names to be deleted.
2048 dpurdie 1847
 
1848
=head2 OPTIONS
1849
 
1850
=over
1851
 
1852
=item B<-path=path>
1853
 
1854
This options specifies the path of the target workspace. If not provided the
1855
command will use the current directory.
1856
 
1857
=back
1858
 
1859
=head2 DESCRIPTION
1860
 
2071 dpurdie 1861
This command can display the branch associated with the workspace or it can
1862
delete one or more branches. It is intended to simplify the deletion of Private
1863
or Development branches.
2048 dpurdie 1864
 
2071 dpurdie 1865
=over 4
1866
 
1867
=item 1 Arguments are provided
1868
 
1869
The command will delete all the named branches. If a named branch does not exist
1870
then the command will issue a warning message.
1871
 
1872
=item 2 No arguments provided
1873
 
1874
The command will display the branch associated with the workspace
1875
 
2048 dpurdie 1876
If the workspace is not linked to a 'branch' then the command will fail.
1877
 
2071 dpurdie 1878
=back
1879
 
311 dpurdie 1880
=head1 Import directory to a Package
1881
 
1882
=head2 NAME
1883
 
1884
Import directory to a Package
1885
 
1886
=head2 SYNOPSIS
1887
 
1888
jats svn [options] import URL [command options]
1889
 
1890
 Options:
1891
    -help[=n]               - Help message, [n=1,2,3]
1892
    -man                    - Full documentation [-help=3]
1893
    -verbose[=n]            - Verbose command operation
1894
 
1895
 Command Options
1896
    -help[=n]               - Command specific help, [n=1,2,3]
1897
    -verbose[=n]            - Verbose operation
1898
    -package=name           - Name of source package
1899
    -dir=path               - Path to new version
379 dpurdie 1900
    -label=label            - Label the result
1901
    -branch=branchName      - Base import on a branch
311 dpurdie 1902
    -replace                - Allow the label to be replaced
1903
    -reuse                  - Reuse the import directory
1904
    -workspace=path         - Path and name of alternate workspace
1905
    -[no]delete             - Deletes workspace after use. Default:yes
379 dpurdie 1906
    -author=name            - Force author of changes
1907
    -date=dateString        - Force date of changes
1908
    -log=text               - Append text to the commit message
1909
    -datafile=path          - Export tag data for automation
2424 dpurdie 1910
    -[no]commit             - Prevent chnages being commited. Default:Yes
1911
    -printfiles=n           - Control commit verbosity
2616 dpurdie 1912
    -nodelete=dirList       - Comma separated list of directores to retain
311 dpurdie 1913
 
1914
=head2 ARGUMENTS
1915
 
1916
The command takes one argument: The URL of the desired package.
1917
This may be be:
1918
 
1919
=over
1920
 
1921
=item * A full URL
1922
 
1923
Complete with protocol and path information.
1924
 
1925
=item * A simple URL
1926
 
1927
JATS will prepend the site-specific repository location to the user provided URL
1928
 
1929
=back
1930
 
1931
=head2 OPTIONS
1932
 
1933
=over
1934
 
1935
=item -help[=n]
1936
 
1937
Print a help message and exit. The level of help may be either 1, 2 or 3.
1938
 
1939
This option may be specified multiple times to increment the help level, or
1940
the help level may be directly specified as a number.
1941
 
1942
=item -verbose[=n]
1943
 
1944
This option will increase the level of verbosity of the utility.
1945
 
1946
If an argument is provided, then it will be used to set the level, otherwise the
1947
existing level will be incremented. This option may be specified multiple times.
1948
 
1949
=item -package=name
1950
 
1951
Either this option or a bare URL on the command line must be provided. It
1952
specifies the repository and package to be used as a basis for the work.
1953
 
1954
=item -dir=path
1955
 
1956
This option is mandatory. It specifies the path to a local directory that
1957
contains a version of the software to be checked in.
1958
 
1959
=item -label=name
1960
 
1961
The resulting software version will be labeled with this tag, if it is provided.
1962
 
383 dpurdie 1963
A label name of TIMESTAMP will be treated in special manner. The name will be
1964
replaced with a unique name based on the users name and the current date time.
1965
 
379 dpurdie 1966
=item -branch=branchName
1967
 
1968
This option will cause the importation to be referenced to the named branch.
1969
If the branch does not exist it will be created. If it does exist then it will
1970
be used.
1971
 
1972
If this option is not specified, then the importation will be based on the 'trunk'.
1973
 
1974
If the Workspace is provided, then it will be used independently of this option.
1975
 
383 dpurdie 1976
A branchName of TIMESTAMP will be treated in special manner. The name will be
1977
replaced with a unique name based on the users name and the current date time.
1978
 
311 dpurdie 1979
=item -replace
1980
 
1981
This option, if provided, allows the label to be replaced.
1982
 
1983
=item -reuse
1984
 
1985
This option can be used to speed the creation of multiple versions in a scripted
1986
environment. The option allows the utility to reuse the workspace if it exists.
1987
 
1988
=item -workspace=path
1989
 
1990
This option specifies an alternate workspace directory to create and use. The
1991
default directory is "SvnImportDir" within the users current directory.
1992
 
1993
=item [no]delete
1994
 
341 dpurdie 1995
This option control the deletion of the workspace directory. By default the
311 dpurdie 1996
directory will be deleted, unless re-use is also used.
1997
 
379 dpurdie 1998
=item -author=name
1999
 
2000
This option will force the author of changes as recorded in the repository.
385 dpurdie 2001
The repository must be configured to allow such changes.
379 dpurdie 2002
 
2003
This option may not work for non-admin users.
2004
 
2005
=item -date=dateString
2006
 
2007
This option will force the date of the changes as recorded in the repository.
385 dpurdie 2008
The repository must be configured to allow such changes.
379 dpurdie 2009
The dateString is in a restricted ISO 8601 format: ie 2009-02-12T00:44:04.921324Z
2010
 
2011
This option may not work for non-admin users.
2012
 
2013
=item -log=text
2014
 
2015
This option will append the specified text to the commit message.
2016
The first line of the commit message is fixed by the import tool.
2017
 
2018
=item -datafile=path
2019
 
2020
This option will cause the utility to create a data file to record the import
2021
tag. It is used for automation of the import process.
2022
 
2424 dpurdie 2023
=item -[no]commit
2024
 
2025
This option will prevent the final workspace from being committed to the
2026
Repository. This allows inspection of the results.
2027
 
2028
The default operation is to commit and label the results of the import.
2029
 
2030
=item -printfiles=n
2031
 
2032
This option controls commit verbosity. The default operation is to display
2033
the files added and removed during the commit.
2034
 
2035
Suitable numbers are: None, 0 (No Display) and 1 (Full Display).
2036
 
2616 dpurdie 2037
=item -nodelete=dirList
2038
 
2039
This option specifies a Comma separated list of directores to be retained
2040
during the import process. This works as via the following mechanism:
2041
 
2042
If the named directory exists in the 'new' image it will replace that in the
2043
'initial' workspace.
2044
 
2045
If the named directory does not exist in the 'new' image, but does exist in the
2046
'initial' image then it will be retained in the 'final' image.
2047
 
311 dpurdie 2048
=back
2049
 
2050
=head2 DESCRIPTION
2051
 
2052
Import a new version of a package to the trunk of the package. The utility
2053
will only import changed files so that file history is preserved within the
2054
repository.
2055
 
2056
This utility is used import software from another version control system
2057
The utility will:
2058
 
2059
=over
2060
 
361 dpurdie 2061
=item *
311 dpurdie 2062
 
361 dpurdie 2063
Create a Work Space based on the current package version
2064
 
379 dpurdie 2065
The 'trunk' of the named package will be used as the base for the workspace,
2066
unless modified with the -branch option.
311 dpurdie 2067
 
361 dpurdie 2068
=item *
311 dpurdie 2069
 
361 dpurdie 2070
Update files and directories
2071
 
311 dpurdie 2072
Determines the files and directories that have been added and deleted and
2073
update the Workspace to reflect the new structure.
2074
 
361 dpurdie 2075
=item *
311 dpurdie 2076
 
361 dpurdie 2077
Check in the new version
311 dpurdie 2078
 
361 dpurdie 2079
=item *
2080
 
2081
Label the new version
2082
 
311 dpurdie 2083
=back
2084
 
2085
=cut
2086