Subversion Repositories DevTools

Rev

Rev 7217 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7217 Rev 7236
Line 1476... Line 1476...
1476
}
1476
}
1477
 
1477
 
1478
#-------------------------------------------------------------------------------
1478
#-------------------------------------------------------------------------------
1479
# Function        : SvnReintegrate
1479
# Function        : SvnReintegrate
1480
#
1480
#
1481
# Description     : Perform an svn merge --reintegrate
1481
# Description     : Simulate an svn merge --reintegrate (which is now deprecated)
-
 
1482
#                       - Assume the user has the 'trunk' in a workspace
-
 
1483
#                       - Ensure there are no uncommitted files
-
 
1484
#                       - Ensure it is upto date with thr REpo server
1482
#                       - with much sanity checking
1485
#                       - with much sanity checking
1483
#                       - auto deterine the correct 'head' to merge from
1486
#                       - verify the named branch
1484
#                       - will delete the branch
1487
#                       - Ensure the named branch is derived from the workspace
1485
#                  
1488
#                       - perform a simple merge
1486
#
1489
#
1487
# Inputs          : None
1490
# Inputs          : None
1488
#
1491
#
1489
# Returns         : 
1492
# Returns         : 
1490
#
1493
#
Line 1493... Line 1496...
1493
    my $opt_path = '.';
1496
    my $opt_path = '.';
1494
    my $opt_info;
1497
    my $opt_info;
1495
    my @mergeOpts;
1498
    my @mergeOpts;
1496
    my $opt_reintegrate;
1499
    my $opt_reintegrate;
1497
    my $opt_dryRun;
1500
    my $opt_dryRun;
-
 
1501
    my $opt_branch;
1498
 
1502
 
1499
    #
1503
    #
1500
    #   Parse more options
1504
    #   Parse more options
1501
    #
1505
    #
1502
    Getopt::Long::Configure('pass_through');
1506
    Getopt::Long::Configure('pass_through');
Line 1505... Line 1509...
1505
                "manual:3"      => \$opt_help,
1509
                "manual:3"      => \$opt_help,
1506
                "path:s"        => \$opt_path,
1510
                "path:s"        => \$opt_path,
1507
                'info'          => \$opt_info,
1511
                'info'          => \$opt_info,
1508
                'reintegrate!'  => \$opt_reintegrate,
1512
                'reintegrate!'  => \$opt_reintegrate,
1509
                'dry-run'       => \$opt_dryRun,
1513
                'dry-run'       => \$opt_dryRun,
-
 
1514
                'branch:s'      => \$opt_branch,
1510
                ) || Error ("Invalid command line" );
1515
                ) || Error ("Invalid command line" );
1511
 
1516
 
1512
    #
1517
    #
1513
    #   Subcommand specific help
1518
    #   Subcommand specific help
1514
    #
1519
    #
1515
    SubCommandHelp( $opt_help, "Reintegrate Merge") if ($opt_help);
1520
    SubCommandHelp( $opt_help, "Reintegrate Merge") if ($opt_help);
1516
 
1521
 
1517
    #
1522
    #
1518
    #   Save merge options
1523
    #   Save merge options
1519
    #   Error if a non-option is present
1524
    #   Extract the named branch ( if not provided via the -branch ) option
1520
    #
1525
    #
1521
    foreach (@ARGV) {
1526
    foreach (@ARGV) {
1522
        if (m~^-~) {
1527
        if (m~^-~) {
1523
            push @mergeOpts, $_;
1528
            push @mergeOpts, $_;
1524
        } else {
1529
        } else {
1525
            Error ("Only options must be passed to Reintegrate: $_");
1530
            Error ("Source branh for the merge must only be specified once") if (defined($opt_branch));
-
 
1531
            $opt_branch = $_;
1526
        }
1532
        }
1527
    }
1533
    }
1528
 
1534
 
-
 
1535
    Error("No branch specified") unless defined $opt_branch;
-
 
1536
    Error("Branch name looks bad") unless ($opt_branch =~ m~[-/a-zA-Z0-9]~i);
-
 
1537
 
1529
    #
1538
    #
1530
    #   We intercepted the dry-run option, so that we know not to delete the Branch
1539
    #   We intercepted the dry-run option,
1531
    #   Put the option back into the stream.
1540
    #   Put the option back into the stream.
1532
    if ($opt_dryRun) {
1541
    if ($opt_dryRun) {
1533
        push @mergeOpts, '--dry-run';
1542
        push @mergeOpts, '--dry-run';
1534
        $opt_reintegrate = 1;
-
 
1535
    }
1543
    }
1536
 
1544
 
-
 
1545
    #
-
 
1546
    #   Calculate the target name
-
 
1547
    #       trunk is special
-
 
1548
    #       tags/... is special
-
 
1549
    if ( $opt_branch eq 'trunk' ) {
-
 
1550
    } elsif ( $opt_branch =~ m~tags/.+~ ) {
-
 
1551
    } else {
-
 
1552
        $opt_branch = join ('/', 'branches', $opt_branch);
-
 
1553
    }
-
 
1554
 
-
 
1555
    #
1537
    #   Check we are in a workspace
1556
    #   Check we are in a workspace
1538
    #   Create an SVN session
1557
    #   Create an SVN session
1539
    #   
1558
    #
1540
    my $uref = NewSessionByWS($opt_path, 0, 1);
1559
    my $uref = NewSessionByWS($opt_path, 0, 1);
-
 
1560
    $uref->{WSURL} =~ m~[^/](/.*)~;
1541
#    DebugDumpData("uref", $uref);
1561
    $uref->{target} = $1;
1542
 
1562
 
1543
    #
1563
    #
1544
    #   Warn user if the command is being executed from within a subdirectory of the workspace
1564
    #   Warn user if the command is being executed from within a subdirectory of the workspace
1545
    #   It might work, but if the directory is deleted it will go badly
1565
    #   It might work, but if the directory is deleted it will go badly
1546
    #
1566
    #
1547
    my $ws_root = mustBeWsRoot($uref);
1567
    my $ws_root = mustBeWsRoot($uref);
-
 
1568
#DebugDumpData("uref", $uref);
-
 
1569
 
-
 
1570
    #
-
 
1571
    #   Validate the branch the user has specified - it must exist
-
 
1572
    #
-
 
1573
    my $ws_url = $uref->Full();
-
 
1574
    my $branch_tag = join ('/', $ws_url, $opt_branch);
-
 
1575
    $uref->SvnValidateTarget (
-
 
1576
                        'cmd'    => 'svn reintegrate',
-
 
1577
                        'target' => $branch_tag,
-
 
1578
                        'require' => 1,
-
 
1579
                        );
1548
 
1580
 
1549
    #
1581
    #
1550
    #   Determine the source of the merge
1582
    #   Verify the source of the merge
1551
    #   Get some more workspace information
1583
    #   Need to get data about the branch, not the current workspace
1552
    # 
1584
    #
-
 
1585
    my $branchRef = NewSessionByUrl($branch_tag);
1553
    $uref->getWsExtraInfo();
1586
    $branchRef->getWsExtraInfo();
1554
    my $logInfo = $uref->{InfoWsExtra};
1587
    my $branchLogInfo = $branchRef->{InfoWsExtra};
1555
#DebugDumpData("getWsExtraInfo", $logInfo);
1588
#DebugDumpData("getWsExtraInfo", $branchLogInfo);
1556
 
1589
 
1557
    # A bit of sanity testing
1590
    # A bit of sanity testing
1558
    Error("Workspace does not appear to be a branch") unless (exists $logInfo->{'copyfrom-path'}); 
1591
    Error("Branch does not appear to be a branch") unless (exists $branchLogInfo->{'copyfrom-path'}); 
1559
    Error("Workspace does not appear to be a branch") unless (exists $logInfo->{'target'}); 
1592
    Error("Branch does not appear to be a branch") unless (exists $branchLogInfo->{'target'}); 
1560
    Error("Workspace is a trunk") if ($logInfo->{'target'} =~ m~/trunk$~);
1593
    Warning("Branch is a trunk") if ($branchLogInfo->{'target'} =~ m~/trunk$~);
1561
    Error("Workspace is a raw branch") if ($logInfo->{'target'} =~ m~/branches$~);
1594
    Error("Branch is a raw branch") if ($branchLogInfo->{'target'} =~ m~/branches$~);
1562
    Error("Workspace is a raw tag") if ($logInfo->{'target'} =~ m~/tags$~);
1595
    Error("Branch is a raw tag") if ($branchLogInfo->{'target'} =~ m~/tags$~);
1563
    Error("Workspace is a within a tag") if ($logInfo->{'target'} =~ m~/tags/~);
1596
    Warning("Branch is a within a tag") if ($branchLogInfo->{'target'} =~ m~/tags/~);
-
 
1597
    Error ("Merging to myself") if ($uref->{target} eq $branchLogInfo->{'target'});
-
 
1598
    Error ("Branch not taken from this trunk", "Workspace: $uref->{'target'}","Branch: $branchLogInfo->{'copyfrom-path'}") unless ($uref->{'target'} eq $branchLogInfo->{'copyfrom-path'});
1564
 
1599
 
1565
    #   Ensure the source is a branch and not a trunk
-
 
1566
    #   Ensure this workspace is not on the same bit (trunk or branch) 
-
 
1567
    #   
-
 
1568
    Message ("Reintegrate Info - No merge performed") if ($opt_info || !$opt_reintegrate);
1600
    Message ("Reintegrate Info - No merge performed") if ($opt_info );
1569
    Message ("RepoRoot: " . $uref->{InfoWs}{'Repository Root'});
1601
    Message ("RepoRoot: " . $uref->{InfoWs}{'Repository Root'});
1570
    Message ("Parent Branch: " . $logInfo->{'copyfrom-path'});
1602
    Message ("Source Branch: " . $branchLogInfo->{'target'});
1571
    Message ("Workspace Branch: " . $logInfo->{'target'} . " <<-- WILL BE DELETED");
1603
    Message ("Workspace Branch: " . $uref->{'target'} );
1572
    Message ("No merge performed.","Use '-reintegrate' to acknolowedge the operation, or '-dry-run'") if (!$opt_info && !$opt_reintegrate);
1604
    Message ("Reintegrate from $branchLogInfo->{'target'} to $uref->{'target'}");
1573
 
1605
 
1574
    #
1606
    #
1575
    #   Examine the workspace and ensure that there are no modified
1607
    #   Examine the workspace and ensure that there are no modified
1576
    #   files - unless they are expected
1608
    #   files - unless they are expected
1577
    #   
1609
    #   
1578
    #   Prevent the user from merging into a WS that has not been committed
1610
    #   Prevent the user from merging into a WS that has not been committed
1579
    #
1611
    #
1580
    $uref->SvnWsModified ( 'cmd' => 'Reintegrate' );
1612
    $uref->SvnWsModified ( 'cmd' => 'Reintegrate' );
1581
 
1613
 
1582
    unless ($opt_info || !$opt_reintegrate) {
1614
    unless ($opt_info) {
1583
        #
-
 
1584
        #   Switch the workspace to the parent
-
 
1585
        #       Must Change directory before we switch
-
 
1586
        #       Otherwise we will import changes into the wrong place
-
 
1587
        #
-
 
1588
        Message ("Switching workspace to : " . $logInfo->{'copyfrom-path'} );
-
 
1589
        chdir ($ws_root) || Error ("Cannot cd to: " . $ws_root);
-
 
1590
        $uref->SvnSwitch ( '^' . $logInfo->{'copyfrom-path'}, '.', '--Print', '--KeepWs' );
-
 
1591
 
1615
 
1592
        #
1616
        #
1593
        #   $logInfo->{'target'} is the branch the workspace was on - before the switch
1617
        #   $branchLogInfo->{'target'} is the branch of the specified branch
-
 
1618
        #   $uref->{target} - should be the same
-
 
1619
        #   
1594
        #   use merge --reintegrate ^/<target> to merge the data into this workspace
1620
        #   use merge ^/<target> to merge the data into this workspace
1595
        #
1621
        #
1596
        #   Perform an interactive command so that the user can accept conflicts - if they want
1622
        #   Perform an interactive command so that the user can accept conflicts - if they want
1597
        #
1623
        #
1598
        Message ("Reintegrate Merge from " . $logInfo->{'target'} . " to " .  $logInfo->{'copyfrom-path'} );
-
 
1599
        my $rv = SvnUserCmd( 'merge', '--reintegrate',
1624
        my $rv = SvnUserCmd( 'merge', '--reintegrate',
1600
                @mergeOpts,
1625
                @mergeOpts,
1601
                '^' . $logInfo->{'target'},
1626
                '^' . $branchLogInfo->{'target'},
1602
                '.',
1627
                '.',
1603
                { 'credentials' => 1 });
1628
                { 'credentials' => 1 });
1604
 
1629
 
1605
        Error ("Merge error", "Workspace has been switched to $logInfo->{'copyfrom-path'}", "Its state is unknown.") if $rv;
-
 
1606
 
-
 
1607
        unless ($opt_dryRun) {
-
 
1608
            #
-
 
1609
            #   The merge appears to be good
-
 
1610
            #   Delete the branch we merged from. Svn Red Book says that it can't be reused ( without a bit more work )
-
 
1611
            #
-
 
1612
            Message("Deleting feature branch: $logInfo->{'target'}");
-
 
1613
 
-
 
1614
            $rv = $uref->SvnDelete (
-
 
1615
                              'target'      => '^' . $logInfo->{'target'},
-
 
1616
                              'comment'   => [$uref->Path().": Delete Branch",'Deleted by user command: jats svn reintegrate as the branch is no longer usable'],
-
 
1617
                              'noerror'   => 1,
-
 
1618
                              );
-
 
1619
            if ($rv) {
-
 
1620
                Error ('SvnReintegrate: Branch not deleted');
-
 
1621
            }
-
 
1622
 
-
 
1623
            Message("Reintegration Merge complete",
-
 
1624
                     "The branch has been deleted: svn $logInfo->{'target'}",
-
 
1625
                     "The workspace has been switched to: $logInfo->{'copyfrom-path'}",
-
 
1626
                     "The workspace needs to be verified and committed."
-
 
1627
                     );
-
 
1628
            }
-
 
1629
        else
-
 
1630
        {
-
 
1631
            Message("Dry Run of the integration merge is complete",
-
 
1632
                   "Quietly switching back to $logInfo->{'target'}");
-
 
1633
            $uref->SvnSwitch ( '^' . $logInfo->{'target'}, '.', '--NoPrint', '--KeepWs' );
-
 
1634
        }
-
 
1635
        exit 0;
-
 
1636
    }
1630
    }
1637
    $opr_done = 1;
1631
    $opr_done = 1;
1638
}
1632
}
1639
 
1633
 
1640
#-------------------------------------------------------------------------------
1634
#-------------------------------------------------------------------------------
Line 2607... Line 2601...
2607
 
2601
 
2608
Reintegrate a Feature Branch
2602
Reintegrate a Feature Branch
2609
 
2603
 
2610
=head2 SYNOPSIS
2604
=head2 SYNOPSIS
2611
 
2605
 
2612
jats svn reintegrate [options]
2606
jats svn reintegrate [options] [branch name]
2613
 
2607
 
2614
 Options:
2608
 Options:
2615
    -help[=n]              - Help message, [n=1,2,3]
2609
    -help[=n]              - Help message, [n=1,2,3]
2616
    -man                   - Full documentation [-help=3]
2610
    -man                   - Full documentation [-help=3]
2617
    -verbose[=n]           - Verbose command operation
2611
    -verbose[=n]           - Verbose command operation
2618
    -path=path             - Target workspace
2612
    -path=path             - Target workspace
2619
    -info                  - Displays merge info only
2613
    -info                  - Displays merge info only
2620
    -dry-run               - Perform a dry run of the merge
2614
    -dry-run               - Perform a dry run of the merge
2621
    -reintegrate           - Option to ensure user is aware of the action
2615
    -branch=name           - The branch to be used as the merge source
2622
    ...                    - Other options are passed to the merge
2616
    ...                    - Other options are passed to the merge
2623
 
2617
 
2624
=head2 ARGUMENTS
2618
=head2 ARGUMENTS
2625
 
2619
 
-
 
2620
If an argument is provided then it will be used as the name of the branch to be merged into
2626
The command takes no arguments, just options.
2621
the current workspace. This is the same as using the -branch option.
2627
 
2622
 
2628
=head2 OPTIONS
2623
=head2 OPTIONS
2629
 
2624
 
2630
=over
2625
=over
2631
 
2626
 
Line 2645... Line 2640...
2645
This option will perform a dry run of the actual merge. It will NOT deleted the feature branch. It will
2640
This option will perform a dry run of the actual merge. It will NOT deleted the feature branch. It will
2646
switch the workspace and after the dry run of the merge it will switch it back.
2641
switch the workspace and after the dry run of the merge it will switch it back.
2647
 
2642
 
2648
This option implies '-reintegrate'.
2643
This option implies '-reintegrate'.
2649
 
2644
 
2650
=item B<-reintegrate>
2645
=item B<-branch>
2651
 
-
 
2652
This option will cause the utility to perform the merge. Without it the utility will provide
-
 
2653
some sanity checking, but will not switch the workspace nor delete the feature branch.
-
 
2654
 
2646
 
2655
By using this option the user acknowledges that the are aware of the changes that will be made.
2647
This option provides an alternate method for specifying the source of the merge.
2656
 
2648
 
2657
=item B<...>
2649
=item B<...>
2658
 
2650
 
2659
Options that are not processed by this command will be passed through to the underlying
2651
Options that are not processed by this command will be passed through to the underlying
2660
'svn merge' command. Available options include:
2652
'svn merge' command. Available options include:
Line 2674... Line 2666...
2674
 
2666
 
2675
The main goal of this command is to avoid situations where developers accidentally merge 
2667
The main goal of this command is to avoid situations where developers accidentally merge 
2676
from the wrong branch, or end up with (to them) inexplicable merge failures and thus 
2668
from the wrong branch, or end up with (to them) inexplicable merge failures and thus 
2677
lose confidence in Subversion. 
2669
lose confidence in Subversion. 
2678
 
2670
 
2679
It will fail if the current working copy is actually on the trunk, and not a branch
2671
It will fail if the specified branch was not tacken from the package's trunk.
2680
 
2672
 
2681
The command will do the following operations:
2673
The command will do the following operations:
2682
 
2674
 
2683
=over 8
2675
=over 8
2684
 
2676
 
Line 2687... Line 2679...
2687
Ensure that the path address a subversion workspace and that the user is not in a sundirectory
2679
Ensure that the path address a subversion workspace and that the user is not in a sundirectory
2688
of the workspace.
2680
of the workspace.
2689
 
2681
 
2690
=item * 
2682
=item * 
2691
 
2683
 
2692
Ensure the workspace is a branch. This command assumes that the workspace contains the feature branch.
2684
Ensure the specified branch exists within the package.
2693
 
2685
 
2694
=item * 
2686
=item * 
2695
 
2687
 
2696
Ensure the workspace contains no modified files
2688
Ensure the workspace contains no modified files
2697
 
2689
 
2698
=item * 
2690
=item * 
2699
 
2691
 
2700
Switch to the branches parent, which may not be the trunk.
2692
Ensure that the specified branch was taken from the branch (often the trunk) on which the 
-
 
2693
workspace is based. A number of other sanity checks are also performed
2701
 
2694
 
2702
=item * 
-
 
2703
 
-
 
2704
Perform the reintegration merge
-
 
2705
 
2695
 
2706
=item * 
2696
=item * 
2707
 
2697
 
2708
Delete the branch, in subversion. Once an reintegration merge has been performed the branch 
2698
Perform the reintegration merge.
-
 
2699
 
2709
can no longer be used. It's not able to correctly absorb new trunk changes, nor can it be properly 
2700
This is, strictly speaking a 'svn merge --reintegrate' as that operation has been deprecated
2710
reintegrated to trunk again. The user may create another branch with the same name, if required.
2701
and was problematic. The effect is the same.
2711
 
2702
 
2712
=back
2703
=back
2713
 
2704
 
2714
At the end of the reintegration merge the workspace will be associated with the parent of the branch, which may be called 'trunk'.
2705
At the end of the reintegration merge the workspace will conatin modified files. The user should verify 
2715
The workspace will contain modified files. It is up to the user to verify that the merge has had the desired result and to commit the
2706
that the merge has had the desired result and to commit the changes.
2716
changes. It is not recommended that development occur in the workspace. A new branch should be created for further development.
-
 
2717
 
2707
 
2718
=cut
2708
=cut
2719
 
2709