Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
VCP::Filter::map(3)   User Contributed Perl Documentation  VCP::Filter::map(3)

       VCP::Filter::map	- rewrite name,	branch_id or delete revisions

	 ## In a .vcp file:

		   name_glob_1<branch_1> name_out_1<branch_result_1>
		   name_glob_2<branch_2> name_out_2<branch_result_2>
		   # ... etc ...

	 ## From the command line:
	  vcp <source> map: name_glob_1<branch_1> name_out_1<branch_result_1> -- <dest>

	 ## you	may have one or	more ( pattern match ) pairs on	the command
	 ## line, ending with --

	 ## the	<branch> part of the maps is optional.

       Maps source files, revisions, and branches to destination files and
       branches	while copying a	repository.  This is done by rewriting the
       "name" and "branch_id" of revisions according to	a list of rules.

       A rule is a pair	of expressions specifying a pattern to match against
       each incoming revision's	name and branch_id and a replacement
       expression specifying the revision's new	name and branch_id.

       The list	of rules is evaluated top down;	the first rule in the list
       that matches is used to generate	the new	name and branch_id.  If	no
       other rules match the implicit default rule is to copy files as is.

   Patterns and	Replacement Expressions
       Patterns	and replacements are each are composed of two subexpressions,
       the "name_expr" and the "branch_id_expr"	like so:


       The "<branch_id_expr>" (including angle brackets) is optional and may
       be forbidden by some sources or destinations that embed the concept of
       a branch	in the name_expr.  (See	VCP::Dest::p4 for an example, though
       this may	be changed in the future).

       For now,	the symbols "#"	and "@"	are reserved for future	used in	all
       expressions and must be escaped using "\", and various shell-like
       wildcards are implemented in pattern expressions.

Pattern	Expressions
       Both the	"name_expr" and	"branch_id_expr" specify patterns using	shell
       regular expression syntax with the extension that parentheses are used
       to extract portions of the match	in to numbered variables which may be
       used in the result construction,	like Perl regular expressions:

	  ?	 Matches one character other than "/"
	  *	 Matches zero or more characters other than "/"
	  ...	 Matches zero or more characters, including "/"
	  (foo)	 Matches "foo" and stores it in	the $1,	$2, etc

       Some example pattern "name_expr"s are:

	  name_expr  Matches
	  =========  =======
	  foo	     the top level file	"foo"
	  foo/bar    the file "foo/bar"
	  ...	     all files (like a missing name_expr)
	  foo/...    all files under "foo/"
	  .../bar    all files named "bar" anywhere
	  */bar	     all files named "bar" one dir down     all files ending in ".pm"
	  ?.pm	     all top level 4 char files	ending in ".pm"
	  \?.pm	     the top level file	"?.pm"
	  (*)/...    all files in subdirs, puts	the top	level dirname in $1

       Unix-style slashes are used, even on operating systems where that may
       not be the preferred local custom.  A pattern consisting	of the empty
       string is legal and matches everything (NOTE: currently there is	no way
       to take advantage of this; quoting is not implemented in	the forms
       parser yet.  use	"..." instead).

       Relative	paths are taken	relative to the	rev_root indicated in the
       source specification for	pattern	"name_expr"s (or in the	destination
       specification for result	"name_expr"s).	For now, a relative path is a
       path that does not begin	with the character "/",	so be aware that the
       pattern "(/)" is	relative.  This	is a limitation	of the implementation
       and may change, until it	does, don't rely on a leading "(" making a
       path relative and use multiple rules to match multiple absolute paths.

       If no "name_expr" is provided, "..." is assumed and the pattern will
       match on	all filenames.

       Some example pattern "branch_id_expr"s are:

	   branch_id_expr  Matches files on
	   =============   ================
	   <>		   no branch label
	   <...>	   all branches	(like a	missing	<branch_id_expr>)
	   <foo>	   branch "foo"
	   <R...>	   branches beginning with "R"
	   <R(...)>	   branches beginning with "R",	the other chars	in $1

       If no "branch_id_expr" is provided, files on all	branches are matched.
       "*" and "..." still match differently in	pattern	"branch_id_expr"s, as
       in <name_expr> patterns,	but this is likely to make no difference, as
       I've not	yet seen a branch label	with a "/" in it.  Still, it is	wise
       to avoid	"*" in "branch_id_expr"	patterns.

       Some example composite patterns are (any	$ variables set	are given in

	   Pattern	      Matches
	   =======	      =======
	   foo<>	      top level	files named "foo" not on a branch
	   (...)<>	      all files	not on a branch	($1)
	   (...)/(...)<>      all files	not on a branch	($1,$2)
	   ...<R1>	      all files	on branch "R1"
	   .../foo<R...>      all files	"foo" on branches beginning with "R"
	   (...)/foo<R(...)>  all files	"foo" on branches beginning with "R" ($1, $2)

       Null characters and newlines are	forbidden in all expressions.

       The characters "#", "@",	"[", "]", "{", "}", ">", "<" and "$" must be
       escaped using a "\", as must any	wildcard characters meant to be	taken

       In result expressions, the wildcard characters "*", "?",	the wildcard
       trigraph	"..." and parentheses must each	be escaped with	single "\" as

       No other	characters are to be escaped.

   Case	sensitivity
       By default, all patterns	are case sensitive.  There is no way to
       override	this at	present; one will be added.

   Result Expressions
       Result expressions look a lot like patthern expressions except that
       wildcards are not allowed and $1	and "${1}" style variable
       interpolation is.

       To explore result expressions, let's look at converting set of example
       files between cvs and p4	repositories.  The difficulty here is that cvs
       and p4 have differing branching implementations.

       Let's assume our	CVS repository has a module named "flibble" with a
       file named "foo/bar" in it.  Here is a branch diagram, with the main
       development trunk shown down the	left (1.1 through 1.6, etc) and	a
       single branch, tagged in	CVS with a branch tag of "beta_1", is shown
       forking off version 1.5:


		 | \
		 |  \ beta_1
		 |   \
		1.6   \
		...    |

	   NOTE	1: You can use C<vcp> to extract graphical branch diagrams by
	   installing AT&T's GraphViz package and the Perl CPAN	module	 Then you can use a command like:

	       $ vcp cvs:/var/cvsroot:flibble/foo/bar \

	   to generate a .png file showing something like the above diagram.

       On the other hand, p4 users typically branch files using	directory
       names.  Here's file "foo/bar" again, with the main trunk	held in	the
       main depot's //depot/main directory, again with a branch	after the 5th
       version of the file, but	this time, the branch is represented by	taking
       a copy


		 | \ //depot/beta_1/foo/bar
		 |  \
		#6   \
		 |   #1
		...   |

	   NOTE	2: the p4 command allows users to branch in very crafty	and
	   creative ways; it does not enforce the semantic of 1	branch per
	   directory, and this gives p4	users a	lot of power and flexibility.
	   It also means that you might	need some pretty crafty	and creative
	   branch maps when converting from p4 to other	repositories.

	   NOTE	3: that	branch looks like a copy, but is actually just a
	   metadata entry in the perforce repository, so it's very low
	   overhead in terms of	server effort and disk space, usually
	   even	more so	than CVS branches.

	   NOTE	4: Using GraphViz (as described	in NOTE	1 above), you can
	   build a diagram like	this using vcp:

	       $ vcp \

       A user may or may not choose to label a branch in p4 with something
       called a	"branch	specification" (see "p4	help branch" for details).
       For this	discussion, we'll assume they didn't.

       First, let's look at cvs	-> p4 conversion.  To do this, we need to
       match the branch	tags in	the CVS	repository and use them	to map
       branched	files in to a p4 subdirectory.	Here's .vcp file for this:

	  ## cvs2p4.vcp

	  # get	all files in the flibble module	from cvs

	  # Put	the files in the flibble directory in the main depot of	p4

	  #   Pattern	    Result
	  #   ============  =======
	      (...)<>	    main/$1   #	main trunk => //depot/flibble/main/...
	      (...)<(...)>  $2/$1     #	branches   => //depot/flibble/$branch/...

       The "Source:" and "Destination:"	fields are just	pieces of a normal
       "vcp" command line moved	in to "cvs2p4.vcp".  The "Map:"	field is a
       list of rules composed of pattern, result expression pairs.

       In this example,	all of the map expressions are relative	paths.	The
       patterns	are relative to	the "Source:" cvs repositories'	""flibble""
       module.	The results are	relative to the	"Destination:" p4
       repositories' ""//depot/flibble/"" directory.

       The first rule maps all files that have no branch tag in	to the p4
       directory "//depot/flibble/main/".  The "(...)<>" pattern has two
       parts: a	"name" part and	a "branch_id" part.  The "name"	part, "(...)",
       matches all path	names and copies them to the $1	variable.  The
       "branch_id" part, " <" >, matches empty / missing "branch_id"s ("vcp"'s
       name for	the CVS	branch tag associated with a file on a branch).	 The "
       main/$1 " result	retrieves the "name" part stored in $1 and prefixes it
       with ""main/"" to build the final "name"	value.

       The second rule maps all	files on branches to an	appropriately named
       subdirectory in the p4 destination.  The	pattern	is a lot like the
       first rule's, but has a "branch_id" part	that matches all "branch_id"s
       and copies them in to $2.  The rule merely uses this "branch_id"	from
       $2 instead of the hardcoded ""main/"" string to place the branches in
       appropriate subdirectories.

       Here's how our flibble/foo/bar file version fare	when passed through
       this mapping:

	   CVS flibble/...		p4 //depot/flibble/...
	   ========================	======================

	   foo/bar#1.1			main/foo/bar#1
	   foo/bar#1.2			main/foo/bar#2
	   ...				...
	   foo/bar#		beta_1/foo/bar#1
	   foo/bar#		beta_1/foo/bar#2
	   ...				...

       It's up to you to be sure there are no branches tagged ""main"" in the
       CVS repository.	Also, no branch	specification will be created in the
       target p4 repository (this is a limitation that should be fixed).

   Result Actions: <<delete>> and <<keep>>
       The result expression "<<delete>>" indicates to delete the revision,
       while the result	expression "<<keep>>" indicates	to pass	it through

	   #   Pattern		  Result
	   #   =================  ==========
	       old_stuff/...	  <<delete>>  #	Delete all files in /old
	       old_stuff/.../*.c  <<keep>>    #	except these

       <<delete>> and <<keep>> may not appear in results; they are standalone

   The default rule
       There is	a default rule

	   ...	<<keep>>  ## Default rule: passes everything through as-is

       that is evaluated after all the other rules.  Thus, if no other rule
       matches a revision, it is passed	through	unchanged.

   Command Line	Parsing
       For large maps or repeated use, the map is best specified in a .vcp
       file.  For quick	one-offs or scripted situations, however, the map:
       scheme may be used on the command line.	In this	case, each parameter
       is a "word" (separated by whitespace) and every pair of words is	a (
       pattern,	result ) pair.

       Because vcp command line	parsing	is performed incrementally and the
       next filter or destination specifications can look exactly like a
       pattern or result, the special token "--" is used to terminate the list
       of patterns provided on the command line.  This may also	be the last
       word in the "Map:" section of a .vcp file, but that is superfluous.  It
       is an error to use "--" before the last word in a .vcp file.

       There is	no way (yet) of	telling	the mapper to continue processing the
       rules list.  We could implement labels like "<label>" to	be allowed
       before pattern expressions (but not between pattern and result),	and we
       could then impelement "<goto label>".  And a "<next>" could be used to
       fall through to the next	label.	All of which is	wonderful, but I want
       to gain some real world experience with the current system and find a
       use case	for gotos and fallthroughs before I implement them.  This
       comment is here to solicit feedback :).

       Barrie Slaymaker	<>

       Copyright (c) 2000, 2001, 2002 Perforce Software, Inc.  All rights

       See VCP::License	("vcp help license") for the terms of use.

perl v5.32.0			  2004-11-04		   VCP::Filter::map(3)


Want to link to this manual page? Use this URL:

home | help