Author: jkeenan Date: Tue Mar 6 16:27:44 2007 New Revision: 17369 Added: branches/buildtools/docs/svn_branching.pod branches/buildtools/lib/Parrot/VersionControl/ branches/buildtools/lib/Parrot/VersionControl/Subversion/ branches/buildtools/tools/util/svn_new_branch.pl (contents, props changed) branches/buildtools/tools/util/svn_synch.pl (contents, props changed)
Log: Contributing tools for management of Subversion branches. Added: branches/buildtools/docs/svn_branching.pod ============================================================================== --- (empty file) +++ branches/buildtools/docs/svn_branching.pod Tue Mar 6 16:27:44 2007 @@ -0,0 +1,279 @@ +# Copyright (C) 2007, The Perl Foundation. +# $Id: svn_branching.pod 17316 2007-03-04 00:17:22Z jkeenan $ + +=head1 NAME + +docs/svn_branching.pod - Why and how to use Subversion branches in Parrot development + +=head1 WHY SHOULD I DO MY DEVELOPMENT IN BRANCHES? + +So that you can minimize the risk of breaking code on which other Parrot +hackers depend. And so that you can maximize your ability to try innovative +approaches to various aspects of Parrot development. + +As Parrot's development advances, more Parrot hackers are making +contributions. Most of those contributions depend on Parrot being more or +less stable and able to pass its tests. Depending on the role which a +particular file plays in the overall build process, a change in such a file +can have a great impact -- for good or for ill -- on the work of many other +hackers. Code should be committed to trunk only when it has been well-tested +and reviewed by your fellow Parrot hackers -- but if you have earned commit +rights, you should have full freedom to develop your ideas in a way that does +not negatively impact on your colleagues. + +=head1 OKAY, HOW DO I DO IT? + +Parrot manages its development with the Subversion version control system. If +you have earned commit rights to the Parrot repository, you presumably already +know how to use these commands: + + svn checkout + svn status + svn add + svn mkdir + svn commit + svn update + svn log + +(If not, start studying the online Subversion book: +L<http://svnbook.red-bean.com/>.) + +However, if you previously used Subversion to manage only smaller projects to +which only a few people made contributions (I<e.g.>, phalanxing a CPAN +module), you may not have needed to learn about Subversion branches and tags. +Here we show you the basics of Subversion branches and tags, then show you +some tools we've hacked up that make branches and tags easier to use for +Parrot development. + +=head2 Subversion Branches + +=head3 What Is a Branch? + +The authors of the Subversion book write: + + ''[A] I<branch> ... [is] a line of development that exists + independently of another line, yet still shares a common history + .... A branch always begins life as a copy of something, and + moves on from there, generating its own history ....'' + +=head3 Branch Creation + +The easiest way of launching a new branch in the Parrot repository is: + + svn copy https://svn.perl.org/parrot/trunk \ + https://svn.perl.org/parrot/branches/my_branch \ + --message "Creating new development branch called my_branch." + +This is a B<cheap copy>; no data is actually duplicated. Instead, as the +Subversion authors write, + + ''[C<svn copy>] ... creates a new directory entry that points to an + I<existing> tree. If you're a Unix user, this is the same concept + as a hard link. From there, the copy is said to be lazy. That is, + if you commit a change to one file within the copied directory, then + only that file changes -- the rest of the files continue to exist as + links to the original files in the original directory.'' + +The implication of lazy copying is that you don't need to fear that you'll be +'taking up too much space in the repository' if you create a new branch. +Moreover, + + ''Subversion has no internal concept of a branch -- only copies. + When you copy a directory, the resulting directory is only a branch + because I<you> attach that meaning to it.'' + +You attach that meaning to the branch by creating it in the part of the Parrot +repository designated for branches: F<https://svn.perl.org/parrot/branches/>. + +=head3 Working with a Branch + +Let's assume you already have the Parrot trunk checked out onto your system in +a directory like this: + + ~/sandbox/parrot/ + +It's best to check out your branch into a directory close to, but distinct +from, the directory where you are keeping the trunk. + + cd ~/sandbox/ + svn checkout https://svn.perl.org/parrot/branches/my_branch my_branch + +You will now see the branch being checked out into newly created directory +F<~/sandbox/my_branch/>. + + cd my_branch/ + +Hack away, committing your changes to the repository branch with the C<svn> +commands you already know. Periodically check the accuracy of the work by +running through Parrot's normal build-and-test cycle: + + perl Configure.pl + make + make test + make realclean + +=head3 Submitting Code Developed in a Branch Back to Trunk + +As of this writing, the Parrot project has not established a uniform policy +with respect to how revisions done in branches should be submitted to/merged +into trunk. So what follows is merely one hacker's opinion as to what +constitutes best practice. + +You originally began to develop in a branch because your work entailed +significant additions or modifications to the code found in Parrot's trunk. +If that was the case, then it doesn't make sense to merge your revisions back +into your sandbox's F<trunk/> directory and then to commit B<directly> to trunk +in the repository. You should allow your fellow Parrot hackers time to review +your revisisions, test them on other operating systems, etc. + +Hence, what you ought to do is do an C<svn update> on your sandbox trunk, then +merge your revisions from your sandbox branch back into your sandbox trunk. +After resolving any conflicts and re-running the build-and-test cycle +described above, you should create a patch for submission to the Parrot RT +system as follows: + + svn diff > porting.my.changes.patch + +See F<docs/submissions.pod> for instructions on submitting patches to Parrot. + +Now, alert readers will recognize that we have skipped over the mechanics of +merging the sandbox branch into the sandbox trunk. That's because the details +are complex and are not handled in the neatest possible way by Subversion. +We refer you to Chapter 4 in the Subversion book for the details. +However, we have developed some Perl utilities which simplify this process. +We'll discuss them in the section on BRANCH MANAGEMENT below. But first, we +need to say something about Subversion tags. + +=head2 Subversion Tags + +In Subversion, a tag is a one-time snapshot of a project that has been given a +human-friendly name. + +A Subversion tag is not fundamentally different from a Subversion branch. +Tags, like branches, are cheap copies of directory trees inside the +repository. Tags, like branches, are created by using the C<svn copy> +command. + +The only thing that distinguishes a tag from a branch is the fact that it is +placed in a part of the repository where, by human convention, it is agreed +that no revisions are ever committed. (If you start making commits to a tag, +then, regardless of where it is found in the repository, it becomes just +another branch.) + +It is often useful to create a tag in the repository to make a note of the +revision number at which you created a branch. Suppose that you created a +branch called C<karmic> and that the revision number of HEAD at that point was +C<17152>. You would want to create a tag named something like: + + karmic-17152 + +The canonical way of creating this tag would be: + + svn copy https://svn.perl.org/parrot/trunk \ + https://svn.perl.org/parrot/tags/karmic-17152 \ + --message "Tag to mark creation of 'karmic' branch at r17152." + +When you no longer need that tag, you can delete it from the repository: + + svn delete https://svn.perl.org/parrot/tags/karmic-17152 \ + --message "Deleting tag which is no longer needed." + +The creation and deletion of tags has been incorporated into some Perl +utilities discussed in the next section. + +=head1 BRANCH MANAGEMENT + +One complication in using branches in a rapidly developing project such as +Parrot is that commits are constantly being made to trunk. Some of those +commits may affect the code you are developing in your branch. Most such +commits will presumably B<not> affect your code if your branch is focused, as +it should be, on a well circumscribed aspect of Parrot's functionality. But, +just in case, you will periodically want to refresh your branch's content with +files that have been updated in trunk since the point you created your branch +(or since your last refresh of the branch). That way, when you decide your +revisions are ready to be submitted as patches back to trunk, you will have +fewer failing tests and fewer conflicts to resolve. + +Jim Keenan (kid51 on #parrot) has developed two Perl programs which enable you +to create a branch so that it is easily refreshed from trunk. Since each of +these programs, as well as the module that underlies them, comes with its own +F<perldoc>-accessible documentation, we won't present all the details here. + +=head2 F<svn_new_branch.pl> + +This program creates a new branch in the Parrot repository under +F<https://svn.perl.org/parrot/branches/>. It also creates a new tag in the +Parrot repository under F<https://svn.perl.org/parrot/tags/>. The tag is used +by a companion program, F<tools/util/svn_synch.pl>, to synchronize your branch +with trunk. + +From the top-level directory in your Parrot sandbox, call: + + perl tools/util/svn_new_branch.pl my_branch + +The program takes one command-line argument: the name you have chosen for +your new branch. + +Since the program writes a tag to the Parrot repository, you will need commit +privileges to use it. + +=head2 F<svn_merge.pl> + +This program makes use of the presence of the tag created by companion program +F<svn_new_branch.pl> to help you keep your branch in synch with the Parrot +trunk. F<svn_synch.pl> updates your sandbox branch with those files which +have been modified in/committed to trunk since you created the branch or since +you last refreshed the branch. It is then up to you to resolve conflicts and +do an F<svn commit> to actually update the branch in the Parrot repository. + +From the top-level directory in your Parrot sandbox, call: + + perl tools/util/svn_synch.pl \ + --branch=my_branch \ + --sandbox=/home/username/path/to/parrot/sandbox + +Two command-line arguments are specified in long-option format: + +=over 4 + +=item * C<--branch> + +The name of the branch in the Parrot repository you created with +F<svn_new_branch.pl>. + +=item * C<--sandbox> + +The absolute path to the directory on your system which you are using for your +ongoing development of the branch. + +=back + +You must now resolve any conflicts, edit as needed, and commit: + + svn resolved fileA + svn resolved fileB + + svn commit + +=head1 AUTHOR + +James E. Keenan ([EMAIL PROTECTED]) + +=head1 ACKNOWLEDGMENTS + +Perrin Harkins sketched out the way to use C<svn copy> and C<svn merge> to +create branches and tags in the way needed for effective branch management. + +Jerry Gay (particle) suggested the creation of this document. + +=head1 SEE ALSO + +Parrot::VersionControl::Subversion::BranchManager. +F<tools/util/svn_new_branch.pl>. +F<tools/util/svn_synch.pl>. +I<Version Control with Subversion>, Ben Collins-Sussman, Brian W Fitzpatrick +and C Michael Pilato (O'Reilly, 2004); L<http://svnbook.red-bean.com/>. +F<docs/submissions.pod>. + +=cut + Added: branches/buildtools/tools/util/svn_new_branch.pl ============================================================================== --- (empty file) +++ branches/buildtools/tools/util/svn_new_branch.pl Tue Mar 6 16:27:44 2007 @@ -0,0 +1,69 @@ +#! perl +# Copyright (C) 2001-2004, The Perl Foundation. +# $Id: svn_new_branch.pl 17314 2007-03-03 22:20:39Z jkeenan $ +use strict; +use warnings; +use lib ("lib"); +use Parrot::VersionControl::Subversion::BranchManager qw( create_new_branch ); + +die "Must supply name of branch to be created as command-line argument" + unless (@ARGV == 1); + +my $branch = shift(@ARGV); + +create_new_branch( { + standard => qq{https://svn.perl.org/parrot}, + branch => $branch, + verbose => 1, +} ); + +exit 0; + +################### DOCUMENTATION ################### + +=head1 NAME + +svn_new_branch.pl - Create new branch in Parrot repository + +=head1 SYNOPSIS + +From the top-level directory in your Parrot sandbox: + + perl tools/util/svn_new_branch.pl my_branch + +=head1 DESCRIPTION + +This program creates a new branch in the Parrot repository under +F<https://svn.perl.org/parrot/branches/>. It also creates a new tag in the +Parrot repository under F<https://svn.perl.org/parrot/tags/>. The tag is used +by a companion program, F<tools/util/svn_synch.pl>. + +The program takes one command-line argument: the name you have chosen for +your new branch. It then invokes +F<Parrot::VersionControl::Subversion::BranchManager::create_new_branch()> to +create the new branch and corresponding tag. + +=head2 Last Tag File + +This program places a hidden file under your +home directory containing the revision number of the HEAD in the Parrot +repository at the time the branch was created. Don't delete it, as its +companion program, F<svn_synch.pl>, needs to read and update that file +to work properly. + +=head1 REQUIREMENTS + +Needless to say, you have to have Subversion installed on your system to use +this program. Since it writes to the Parrot repository, you will need commit +privileges as well. + +=head1 AUTHOR + +James E Keenan ([EMAIL PROTECTED]) + +=head1 SEE ALSO + +F<tools/util/svn_synch.pl>. Parrot::VersionControl::Subversion::BranchManager. +F<docs/svn_branching.pod>. + +=cut Added: branches/buildtools/tools/util/svn_synch.pl ============================================================================== --- (empty file) +++ branches/buildtools/tools/util/svn_synch.pl Tue Mar 6 16:27:44 2007 @@ -0,0 +1,114 @@ +#! perl +# Copyright (C) 2007, The Perl Foundation. +# $Id: svn_synch.pl 17314 2007-03-03 22:20:39Z jkeenan $ +use strict; +use warnings; +use Getopt::Long; +use lib ("lib"); +use Parrot::VersionControl::Subversion::BranchManager qw( + synch_branch_to_trunk +); + +my ($branch, $sandbox); + +GetOptions( + "branch=s" => \$branch, + "sandbox=s" => \$sandbox, +); +die "Must supply name of branch you are working with to '--branch' option" + unless $branch; +die "Must supply absolute path to your sandbox directory to '--sandbox' option" + unless $sandbox; + +synch_branch_to_trunk( { + standard => qq{https://svn.perl.org/parrot}, + branch => $branch, + sandbox => $sandbox, + verbose => 1, +} ); + +exit 0; + +################### DOCUMENTATION ################### + +=head1 NAME + +svn_synch.pl - Synchronize Parrot branch to trunk + +=head1 SYNOPSIS + +From the top-level directory in your Parrot sandbox: + + perl tools/util/svn_synch.pl \ + --branch=my_branch \ + --sandbox=/home/username/path/to/parrot/sandbox + +Then: resolve any conflicts and commit: + + svn resolved fileA + svn resolved fileB + + svn commit + +=head1 DESCRIPTION + +Use this program if you are managing development in a new branch in the Parrot +repository which you created with its companion program +F<tools/util/svn_new_branch.pl>. + +In addition to creating a new branch in the Parrot repository, +F<svn_new_branch.pl> creates a tag whose name follows the pattern +C<my_branch-NNNNN>, where C<NNNNN> is the Subversion revision number at +the point where the branch was created. + +This program, F<svn_synch.pl>, makes use of the presence of that tag to help +you keep your branch in synch with the Parrot trunk. You develop in a branch +to make sure your development doesn't break anything in trunk -- but from +time-to-time you also want to make sure that your branch gets the latest +versions of files recently committed to trunk. F<svn_synch.pl> updates your +local sandbox directory for the branch with those updated files. It is then +up to you to resolve conflicts and do an F<svn commit> to actually update the +branch in the Parrot repository. + +=head2 Arguments + +Two command-line arguments specified in long-option format: + +=over 4 + +=item * C<--branch> + +The name of the branch in the Parrot repository you created with +F<svn_new_branch.pl>. + +=item * C<--sandbox> + +The absolute path to the directory on your system which you are using for your +ongoing development of the branch. + +=back + +=head2 Last Tag File + +The companion program, F<svn_new_branch.pl>, places a hidden file under your +home directory containing the revision number of the HEAD in the Parrot +repository at the time the branch was created. Don't delete it, as this +program needs to read and update that file to work properly. + +=head1 REQUIREMENTS + +Needless to say, you have to have Subversion installed on your system to use +this program. Since it writes to the Parrot repository, you will need commit +privileges as well. + +=head1 AUTHOR + +James E Keenan ([EMAIL PROTECTED]) + +=head1 SEE ALSO + +F<tools/util/svn_new_branch.pl>. +Parrot::VersionControl::Subversion::BranchManager. +F<docs/svn_branching.pod>. + +=cut
