Subversion Repositories DevTools

Rev

Rev 1347 | Rev 1380 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
267 dpurdie 1
########################################################################
2
# Copyright (C) 1998-2004 ERG Limited, All rights reserved
3
#
4
# Module name   : jats_svnlabel.pl
5
# Module type   : Jats Utility
6
# Compiler(s)   : Perl
7
# Environment(s): Jats
8
#
9
# Description   : A script to perform a number of labeling operations
10
#                 The script will:
11
#                   label a workspace       - Create a tag
12
#                   delete a label          - Deletes a tag
13
#                   rename a label          - Renames a tag
14
#                   clone a label           - Clones a tag
15
#
16
#......................................................................#
17
 
18
require 5.006_001;
19
use strict;
20
use warnings;
21
use JatsError;
22
use JatsSvn;
23
 
24
use Pod::Usage;                             # required for help support
25
use Getopt::Long;
26
use Cwd;
27
 
28
my $VERSION = "1.0.0";                      # Update this
29
 
30
#
31
#   Options
32
#
33
my $opt_debug   = $ENV{'GBE_DEBUG'};        # Allow global debug
34
my $opt_verbose = $ENV{'GBE_VERBOSE'};      # Allow global verbose
35
my $opt_help = 0;
36
my $opt_check;
37
my $opt_avail;
38
my $opt_label;
39
my $opt_replace;
40
my $opt_delete;
41
my $opt_rename;
42
my $opt_clone;
43
my $opt_comment;
44
my $opt_workspace;
45
my $opt_packagebase;
46
my $opt_branch;
47
my $opt_list;
385 dpurdie 48
my $opt_author;
49
my $opt_date;
50
my $opt_complexTag;
1356 dpurdie 51
my $opt_noUpdateCheck;
267 dpurdie 52
 
53
#
54
#   Globals
55
#
56
my $session;                                # Subversion Session
57
my $label;                                  # User argument - one label
58
my $src_label;                              # User specified source label
59
my $pkg_root;                               # Root of corresponding package
60
my $opr_done;                               # User has done something
61
 
62
#-------------------------------------------------------------------------------
63
# Function        : Mainline Entry Point
64
#
65
# Description     :
66
#
67
# Inputs          :
68
#
69
my $result = GetOptions (
385 dpurdie 70
                'help:+'        => \$opt_help,              # flag, multiple use allowed
71
                'manual:3'      => \$opt_help,              # flag
72
                'verbose:+'     => \$opt_verbose,           # flag, multiple use allowed
73
                'check'         => \$opt_check,             # Flag
74
                'available'     => \$opt_avail,             # Flag
75
                'label'         => \$opt_label,             # Flag
76
                'auto'          => \$opt_label,             # Same as -label
77
                'delete'        => \$opt_delete,            # Flag
78
                'replace!'      => \$opt_replace,           # Flag
79
                'rename=s'      => \$opt_rename,            # String
80
                'clone=s'       => \$opt_clone,             # String
81
                'comment=s'     => \$opt_comment,           # String
82
                'workspace=s'   => \$opt_workspace,         # String
83
                'packagebase=s' => \$opt_packagebase,       # String
84
                'branch'        => \$opt_branch,            # Flag
85
                'list'          => \$opt_list,              # Flag
86
                'author=s'      => \$opt_author,            # String
87
                'date=s'        => \$opt_date,              # String
1270 dpurdie 88
                'allowlocalmods!'   => \$opt_complexTag,    # [no]aaaaaa
1356 dpurdie 89
                'allowRepoChanges!'   => \$opt_noUpdateCheck, # [no]aaaaaa
90
 
267 dpurdie 91
                );
92
 
93
                #
94
                #   UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!
95
                #
96
 
97
#
98
#   Process help and manual options
99
#
100
pod2usage(-verbose => 0, -message => "Version: $VERSION") if ($opt_help == 1 || ! $result);
101
pod2usage(-verbose => 1) if ($opt_help == 2 );
102
pod2usage(-verbose => 2) if ($opt_help > 2);
103
 
104
#
105
#   Configure the error reporting process now that we have the user options
106
#
107
ErrorConfig( 'name'    =>'SVNLABEL',
108
             'verbose' => $opt_verbose,
109
            );
110
 
111
#
112
#   Validate user options
113
#   Need one command line argument
114
#
115
Error ("No labels provided") if ( $#ARGV < 0 && !$opt_list );
116
Error ("Too many labels provided") if ( $#ARGV > 0);
375 dpurdie 117
Error ("Conflicting options. Clone and Label") if ( $opt_clone && $opt_label );
118
Error ("Conflicting options. Rename and Label") if ( $opt_rename && $opt_label );
267 dpurdie 119
$label = $ARGV[0];
1347 dpurdie 120
$label =~ s~^SVN::~~ if $label;
267 dpurdie 121
 
122
#
123
#   Locate package and workspace roots
124
#
125
LocateRoots ();
126
 
127
################################################################################
128
#
129
#   Validate one or more labels
130
#   Intended to be used within scripts for testing
131
#
132
if ( $opt_check )
133
{
134
    $session->SvnValidateTarget
135
    (
136
        'target'    => make_src_label ($pkg_root, $label),
341 dpurdie 137
        'cmd'       => 'Validate Existence',
267 dpurdie 138
        'require'   => 1,
139
    );
140
    $opr_done = 1;
141
}
142
 
143
if ( $opt_avail )
144
{
145
    $session->SvnValidateTarget
146
    (
147
        'target'    => make_src_label ($pkg_root, $label),
148
        'cmd'       => 'Validate Availablility',
149
        'available' => 1,
150
    );
151
    $opr_done = 1;
152
}
153
 
154
################################################################################
155
#
156
#   List labels
157
#
158
if ( $opt_list )
159
{
160
    my $pList = $session->ListLabels (make_label ($pkg_root, '') );
161
 
162
    #
379 dpurdie 163
    #   Remove trailing / on all directory names
267 dpurdie 164
    #
165
    chop @{$pList};
166
 
167
    my $type = $opt_branch ? 'branch' : 'tag';
168
    Information ( "Package: " . $session->Path,
169
                    ,map ( $type . ': ' . $_, @{$pList})
170
                    );
171
    $opr_done = 1;
172
}
173
 
174
 
175
################################################################################
176
#
177
#   Rename a label
178
#   This has implications for stuff that is stored within release manager
179
#
180
#   Renaming a pegged version is problematical
181
#   At the moment we do a copy ( rename, without the delete)
182
#
183
if ( $opt_rename )
184
{
185
    #
186
    #   Create old and new paths for the full label
187
    #
188
    my $ws_label_old = make_src_label ($pkg_root, $label);
1347 dpurdie 189
    my $label_new = SvnIsaSimpleLabel($opt_rename);
190
    my $ws_label_new = make_label ($pkg_root , $label_new);
267 dpurdie 191
 
192
    $session->SvnRename (
193
                'old' => $ws_label_old,
194
                'new' => $ws_label_new,
195
                'comment' => $opt_comment ? $opt_comment : 'Renamed by Jats Svnlabel',
196
                'replace' => $opt_replace ? 1 : 0,
197
                );
198
 
199
    Message ("Repository Ref: " . $session->RmRef);
1347 dpurdie 200
    Message ("Vcs Tag       : " . $session->SvnTag);
385 dpurdie 201
    updateProperties();
267 dpurdie 202
    $opr_done = 1;
203
}
204
 
205
################################################################################
206
#   
207
#   The Svn Label need a package root
208
#   If we are in a WorkSpace, then we can determine the package root
209
#
210
if ( $opt_label )
211
{
212
    #
213
    #   Can now create a nice pathname for the label
214
    #
1347 dpurdie 215
    $label = SvnIsaSimpleLabel ($label);
216
    my $ws_label = make_label( $pkg_root, $label );
267 dpurdie 217
 
218
    #
219
    #   Don't let the user create a tag from a workspace that is
220
    #   also created from a tag.
221
    #
222
    #   They should be using a branch.
223
    #   Can't stop them - but can make it difficult.
224
    #
225
    Error ("Cannot tag a Workspace based on a 'tag'",
226
           "You should be working in a branch",
227
           "WorkSpace: $session->{WSURL}" )
379 dpurdie 228
        if ( !$opt_branch && (($session->WsType) eq 'tags') );
267 dpurdie 229
 
1328 dpurdie 230
    #
231
    #   The label operation *should* be a server side operation only
1356 dpurdie 232
    #   If the user has commited changes, but not yet updated the local
1328 dpurdie 233
    #   workspace, then subversion will do a client side copy
234
    #   This is not good.
235
    #       If the 'tags' area is not writable then we get a cryptic message
236
    #       If the 'tags' area is writable then we commit the changes twice
237
    #
238
    #   Solution - ensure that the Workspace is upto date
239
    #              This is done within SvnCopyWs
240
    #
267 dpurdie 241
    $session->SvnCopyWs (
242
                   target => $ws_label,
385 dpurdie 243
                   'allowLocalMods' => $opt_complexTag,
1356 dpurdie 244
                   'noupdatecheck' => $opt_noUpdateCheck,
267 dpurdie 245
                   'noswitch' => 1,
246
                   'replace' => $opt_replace ? 1 : 0,
247
                   'comment' => $opt_comment ? $opt_comment : 'Created by Jats Svnlabel',
248
                   );
249
 
250
    Message ("Repository Ref: " . $session->RmRef);
1347 dpurdie 251
    Message ("Vcs Tag       : " . $session->SvnTag);
385 dpurdie 252
    updateProperties();
267 dpurdie 253
    $opr_done = 1;
254
}
255
 
256
################################################################################
257
#
258
#   Delete a label
259
#   Can't really delete one, but we can remove it from the head
260
#   If SVN ever gets an 'obliterate' command then prehaps we could use it
261
#
262
if ( $opt_delete )
263
{
264
    #
265
    #   Calculate the label name to delete
266
    #
267
    my $ws_label = make_src_label( $pkg_root, $label );
268
    $session->SvnDelete ( 'target' => $ws_label,
269
                          'comment' => $opt_comment ? $opt_comment : 'Deleted by Jats Svnlabel',
1270 dpurdie 270
                          'noerror' => 0 );
267 dpurdie 271
    $opr_done = 1;
272
}
273
 
274
################################################################################
275
#
276
#   Clone a label
277
#   Essentially a copy of a tag
278
#
279
#
280
if ( $opt_clone )
281
{
282
    #
283
    #   Create old and new paths for the full label
284
    #
285
    my $ws_label_old = make_src_label ($pkg_root, $label);
1347 dpurdie 286
    my $new_label = SvnIsaSimpleLabel($opt_clone);
287
    my $ws_label_new = make_label ($pkg_root , $new_label);
1341 dpurdie 288
    #
289
    #   Backtrack label so that we clone the tag source, not the tag
290
    #
291
    if ( $ws_label_old =~ m~/tags/~ )
292
    {
1356 dpurdie 293
        $ws_label_old = $session->backTrackSvnLabel( 'tags/' . $label, savedevbranch => 1);
1341 dpurdie 294
        Verbose2 ("Tag back tracked to: $ws_label_old");
295
        $ws_label_old = $pkg_root . '/' . $ws_label_old;
296
    }
297
 
267 dpurdie 298
    $session->SvnCopy (
299
                'old' => $ws_label_old,
300
                'new' => $ws_label_new,
1341 dpurdie 301
                'comment' => $opt_comment ? $opt_comment : 'Copied by Jats Svnlabel Clone',
267 dpurdie 302
                'replace' => $opt_replace ? 1 : 0,
303
                );
304
    Message ("Repository Ref: " . $session->RmRef);
1347 dpurdie 305
    Message ("Vcs Tag       : " . $session->SvnTag);
385 dpurdie 306
    updateProperties();
267 dpurdie 307
    $opr_done = 1;
308
}
309
 
310
 
311
Error ("No valid operations specified. Try -h") unless ( $opr_done );
312
exit 0;
313
 
314
 
315
#-------------------------------------------------------------------------------
316
# Function        : make_label
317
#
318
# Description     : Create a label ( tag or branch )
319
#
320
# Inputs          : $base
321
#                   $name
322
#
323
# Returns         : Full label
324
#
325
sub make_label
326
{
327
    my ($base, $name) = @_;
328
    my $join = $opt_branch ? '/branches/' : '/tags/';
329
    return $base . $join . $name;
330
}
331
 
332
#-------------------------------------------------------------------------------
333
# Function        : make_src_label
334
#
335
# Description     : Create a source label ( tag or branch )
336
#
1341 dpurdie 337
#                   Calculation may be bypassed if the global $src_label
379 dpurdie 338
#                   is specified.
339
#
267 dpurdie 340
# Inputs          : $base
379 dpurdie 341
#                   $name           - May contain hint
342
#                                     Prefixed with 'tags/' or 'branches/'
267 dpurdie 343
#
344
# Returns         : Full label
345
#
346
sub make_src_label
347
{
348
    return $src_label if ( $src_label );
349
    my ($base, $name) = @_;
379 dpurdie 350
    my $result = $name;
1328 dpurdie 351
    unless ( $name =~ m~(^branches/)|(^tags)|(^trunk\@)~ )
379 dpurdie 352
    {
353
        $result = ($opt_branch ? 'branches/' : 'tags/' ) . $name;
354
    }
355
    return $base . '/' . $result;
267 dpurdie 356
}
357
 
358
 
359
#-------------------------------------------------------------------------------
360
# Function        : LocateRoots
361
#
362
# Description     : Determine workspace root and associated
363
#                   package root
364
#
365
#                   Uses several hint to figure it out
366
#                       The default is the package in the current directory
367
#                       -workspace - may address a workspace
368
#                       -packagebase - may specify a package base
369
#                                      Does not work with -label
370
#                                      as we need a workspace
371
#
372
#
373
# Inputs          : None - uses globals
374
#
375
# Returns         : Setup global variables
376
#
377
sub LocateRoots
378
{
379
    #
380
    #   Use current directory as the workspace unless the user
381
    #   has specified a different one
382
    #
383
    $session = NewSessionByWS( $opt_workspace || '.', $opt_workspace ? 0 : 1 );
384
 
385
    Verbose ("Determine the current workspace root" );
386
    my $ws_root = $session->SvnLocateWsRoot(1) || '';
387
 
388
    #
389
    #   Only need a WS root for the label operation
390
    #   Every thing else can live without it
391
    #
392
    Error ("Cannot determine source Workspace") if ( $opt_label && !$ws_root );
393
 
394
    #
395
    #   Calculate the package base
396
    #       - User specified
397
    #       - Extacted from label
398
    #       - Extracted from WorkSpace
399
    #           - User specified Workspace
400
    #           - Current directory
401
    #
402
    if ( $opt_packagebase )
403
    {
404
        #
405
        #   User has given us the package base
406
        #
361 dpurdie 407
        $session = NewSessionByUrl ( $opt_packagebase, 0, $session );
267 dpurdie 408
        $session->SvnValidatePackageRoot();
409
    }
375 dpurdie 410
    elsif ( (!$opt_label ) && $label && $label =~ m~(.+)(/(tags|branches|trunk)(/|@)(.+))~ )
267 dpurdie 411
    {
412
        #
375 dpurdie 413
        #   Attempt to extract it from the label, but only if we are not
414
        #   labeling a sandbox.
267 dpurdie 415
        #   Remove it from the label
416
        #
417
        $src_label = $2;
418
        $label = $5;
361 dpurdie 419
        $session = NewSessionByUrl ( $1, 0, $session );
267 dpurdie 420
        $session->SvnValidatePackageRoot();
421
        $src_label = $session->Full . $src_label;
422
    }
423
    elsif ( $ws_root )
424
    {
425
        # $s2 = $session;
426
    }
427
    else
428
    {
429
        Error ("Cannot determine the Package Base");
430
    }
431
    $pkg_root = $session->Full;
432
 
433
    #
434
    #   Everything needs a $pkg_root
435
    #
436
    Error ("Cannot determine Package Base") unless ( $pkg_root  );
437
 
438
    Verbose ("Workspace root: $ws_root");
439
    Verbose ("Package root  : $pkg_root");
440
#DebugDumpData ("Session", $session );
441
}
442
 
443
#-------------------------------------------------------------------------------
385 dpurdie 444
# Function        : updateProperties
445
#
446
# Description     : Update the properties, if present
447
#
448
# Inputs          : Globals
449
#
450
# Returns         : Nothing
451
#
452
sub updateProperties
453
{
454
    $session->setRepoProperty('svn:author', $opt_author) if (defined ($opt_author));
455
    $session->setRepoProperty('svn:date', $opt_date) if (defined ($opt_date));
456
}
457
 
458
#-------------------------------------------------------------------------------
267 dpurdie 459
#   Documentation
460
#
461
 
462
=pod
463
 
361 dpurdie 464
=for htmltoc    GENERAL::Subversion::
465
 
267 dpurdie 466
=head1 NAME
467
 
468
jats_svnlabel - Subversion label operations
469
 
470
=head1 SYNOPSIS
471
 
361 dpurdie 472
jats svnlabel [options] C<label>
267 dpurdie 473
 
474
 Options:
475
    -help                  - brief help message
476
    -help -help            - Detailed help message
477
    -man                   - Full documentation
385 dpurdie 478
    -available             - Check for label availability
267 dpurdie 479
    -check                 - Check for label existence
480
    -clone=xxx             - Clone a package version
481
    -delete                - Delete label from the repository
482
    -label                 - Labels a Package
383 dpurdie 483
    -auto                  - Same as -label
385 dpurdie 484
    -list                  - List labels in a package
267 dpurdie 485
    -rename=xxx            - Rename a label
385 dpurdie 486
 
267 dpurdie 487
 Modifiers
488
    -branch                - Use branches, not tags
489
    -replace               - Replace existing labels. Use with -label
490
    -comment=text          - Comment to add to repository operations
491
    -workspace=path        - Path to a workspace to label
385 dpurdie 492
    -packagebase=path      - Repository path to package base
493
    -author=name           - Force author of changes
494
    -date=dateString       - Force date of changes
495
    -allowLocalMods        - Allow complex tagging
1356 dpurdie 496
    -allowRepoChanges      - Supress check for an up to date workspace
267 dpurdie 497
 
498
=head1 OPTIONS
499
 
500
=over 8
501
 
502
=item B<-help>
503
 
504
Print a brief help message and exits.
505
 
506
=item B<-help -help>
507
 
508
Print a detailed help message with an explanation for each option.
509
 
510
=item B<-man>
511
 
512
Prints the manual page and exits.
513
 
514
=item B<-clone=xxx>
515
 
385 dpurdie 516
This option will copy a labeled version of a package to a new label.
267 dpurdie 517
 
518
=item B<-delete>
519
 
520
This option will delete the specified label from the repository
521
 
522
=item B<-available>
523
 
385 dpurdie 524
This option will check for the labels non-existence. An error will be reported
267 dpurdie 525
if the label exists.
526
 
527
=item B<-check>
528
 
385 dpurdie 529
This option will check for the labels existence. An error will be reported
267 dpurdie 530
if the label does not exist.
531
 
532
=item B<-label>
533
 
534
This option will label a workspace.
535
 
536
The -replace option may be used to force labels to be moved.
537
 
383 dpurdie 538
=item B<-auto>
539
 
540
This option is the same as '-label'. It is provided for compatibility with other
541
labeling tools.
542
 
267 dpurdie 543
=item B<-rename=xxx>
544
 
545
This option will rename a label. The new name of the label is provided as the
546
argument after the option. If any further operation are to be performed the
547
new label name will be used.
548
 
549
=item B<-list>
550
 
385 dpurdie 551
This option will case all labels for the related package to be shown. The
267 dpurdie 552
command assumes that the repository is in a trunk/tags/branches format.
553
 
554
By default tags are shown. Branches may be shown with the -branches option.
555
 
556
=item B<-replace>
557
 
558
This option may be used with the -label command to allow existing labels to
559
be replaced.
560
 
561
=item B<-comment=text>
562
 
563
This option provides text to be used to document the operation in the log.
564
 
565
If none is provided, then the utility will use a simple comment of its own.
566
 
567
=item B<-workspace=path>
568
 
569
This option can be used to specify the path to a workspace to be labeled.
570
 
571
If not provided then the utility will use the current directory to determine
572
the root of the workspace.
573
 
574
=item B<packagebase=path>
575
 
576
This option can be used to specify the path to a package within a repository.
577
 
578
If the 'label' contains a package base, then it will be extracted and used.
579
 
580
If not provided and the utility is within a workspace, then the package base will
581
be taken to be that of the package in the workspace.
582
 
583
=item B<-branch>
584
 
585
This option modifies all commands. It causes the labeling operations to be
1341 dpurdie 586
performed on a packages 'branches' area instead of the default 'tags'
267 dpurdie 587
area.
588
 
385 dpurdie 589
=item -author=name
590
 
591
This option will force the author of changes as recorded in the repository.
592
The repository must be configured to allow such changes.
593
 
594
This option may not work for non-admin users.
595
 
596
=item -date=dateString
597
 
598
This option will force the date of the changes as recorded in the repository.
599
The repository must be configured to allow such changes.
600
The dateString is in a restricted ISO 8601 format: ie 2009-02-12T00:44:04.921324Z
601
 
602
This option may not work for non-admin users.
603
 
604
=item -allowLocalMods
605
 
606
This option modifies the checking that is done when the workspace is labeled.
607
The default is to 'not' allow local modifications. All modifications must be
608
committed before the label is created.
609
 
610
If local modifications are allowed, then the utility will warn about local
611
modifications, but the labelling process will continue. This allows
612
for 'complex' tagging. The modified files will be transferred to the repository
613
and will form a part of the tag.
614
 
615
This mode of operation should NOT be used for normal labeling. It is useful for
616
the preservation of 'Mixed Workspaces'.
617
 
1356 dpurdie 618
=item -allowRepoChanges
619
 
620
This option modifies the checking that is done when the workspace is labeled.
621
The default is to 'not' allow changes between the Workspace and the Repository.
622
Normally the Workspace must be up to date with respect to the head of the
623
development branch.
624
 
625
If Repository Changes are allowed, then the utility will warn about changes, but
626
the labelling process will continue. This allows Workspaces that have been
627
pegged to old versions to be tagged.
628
 
629
The Repository may still reject the tag if the workspace has been modified in
630
a manner that would result in a client-side copy. This is intentional.
631
 
267 dpurdie 632
=back
633
 
634
=head1 DESCRIPTION
635
 
636
This program provides a number of useful Subversion labeling operations. These
637
are:
638
 
639
=over 8
640
 
361 dpurdie 641
=item   *
267 dpurdie 642
 
385 dpurdie 643
check - check existence of a label
267 dpurdie 644
 
361 dpurdie 645
=item   *
267 dpurdie 646
 
385 dpurdie 647
available - check non-existence of a label
267 dpurdie 648
 
361 dpurdie 649
=item   *
267 dpurdie 650
 
375 dpurdie 651
list - list the labels on a package
267 dpurdie 652
 
361 dpurdie 653
=item   *
267 dpurdie 654
 
361 dpurdie 655
rename - rename a label
656
 
657
=item   *
658
 
659
label - label a workspace
660
 
661
=item   *
662
 
663
delete - delete a label
664
 
665
=item   *
666
 
667
clone - duplicate a label
668
 
267 dpurdie 669
=back
670
 
671
The various operations may be mixed in the one command. The order of the
672
operations is: check, available, list, rename, label, delete and clone
673
 
674
=head2 LABEL format
675
 
676
A 'label' as used by JATS within a Subversion repository, may have four elements.
677
These are:
678
 
679
=over
680
 
681
=item   * Package Path
682
 
385 dpurdie 683
Any text proceeding a / will be taken to be a package path. This identifies the
267 dpurdie 684
root of the package within the repository.
685
 
686
=item   * Label Type
687
 
688
This will be one of 'trunk', 'branches' or 'tags'.
689
 
690
Normally labels are placed on the 'tags' subdirectory of a package.
691
 
692
=item   * Simple Label
693
 
341 dpurdie 694
The label tag. It can only contain Alphanumerics and the characters :-_.
267 dpurdie 695
In practice this can be a simple version number as the labels are held the
696
context of a package.
697
 
383 dpurdie 698
A simple label of TIMESTAMP will be treated in special manner. The name will be
699
replaced with a unique name based on the users name and the current date time.
700
 
267 dpurdie 701
=item   * Peg
702
 
703
A peg consists of a '@' and a number string at the end of the label.
704
 
705
=back
706
 
707
An example of a full label is: repo/package/component/tags/label_text@1234
708
 
709
Not all operation support the full label syntax. The 'peg' is not allowed in
710
a label that will be used as a target of a repository copy operation, nor
711
is the 'Package Path'.
712
 
713
Full labels can be used in operations that specify the source of a
714
copy operation, such as a delete, rename or clone operation.
715
 
716
All operations report a 'Full Label' that can be used to reference the
341 dpurdie 717
repository at any time in the future. This is the 'tag' that needs to be
267 dpurdie 718
provided to 'Release Manager in order to reproduce the package.
719
 
720
=head1 EXAMPLE
721
 
722
jats svnlabel -label daf_br_23.0.0.syd
723
 
724
=cut
725