May 5, 2016

P4 Alias

Integration

Command Secrets Revealed

Did you know that the Helix server has always had aliases? If you type:

 p4 workspaces

at your command prompt, you will find that this command does the same thing as:

p4 clients

The same is true, for example, for the commands p4 password (p4 passwd) and my favorites p4 rec (p4 reconcile) and p4 clean (p4 reconcile –w).

But these aliases are defined by the server, which calls them synonyms, and they get updated very rarely. In the past, if you wanted to define your own aliases you would either have had to use the (not so secret anymore) REWRITE option of the P4Broker or write a script, losing the benefit of the simple P4 command.

Not anymore! The new 2016.1 release of Perforce Helix (to be precise, you only need the latest Helix Client P4) adds the ability to define your own aliases in your local environment. Let me explain the setup and reporting first before I go into the details of what exactly you can do with aliases.

 

P4ALIASES and the .p4aliases file

The default name and location for the aliases configuration file is .p4aliases and resides in your home directory[1]. It is a simple text file of the form “alias = transformation”. You can create additional custom alias files, but you must “point” to them using the P4ALIASES environment variable to make them active:

export P4ALIASES=~/.my-other-p4aliases

The most useful way to do this is probably to add the following line to your P4CONFIG file:

P4ALIASES=$configdir/.p4aliases

This will use the alias file located wherever your P4CONFIG file resides, typically your workspace root. This format allows you to have different aliases for each workspace, if you so choose.

 

Reporting

Which aliases do you have defined? I am glad you asked ...

$ p4 aliases
Perforce client info:
You have no aliases defined.

Fair enough, we haven’t created any aliases yet. Let’s change that and create an alias file in our home directory:

$ echo "commit = submit" > .p4aliases

This is for those users who migrated from Subversion, Mercurial, or Git to Perforce. Now we can invoke commit as an alias for the submit command:

$ p4 commit

To see which real command will be used, we can run


     $ p4 –aliases=dry-run commit

p4 submit

Now we are all set to explore the magic of aliases.

 

Simple synonyms

The easiest application of aliases is a simple synonym for another command, like the ones already defined by the server. This can include additional parameters, such as:


     blame = annotate –u

Any additional parameters and file arguments passed to this new p4 blame are simply added to the resulting p4 annotate command.

 

Formatted output

The output of P4 can be modified by using tagged mode and formatting. Tagged mode tells the server to return any date in key/value pairs, and the formatted output makes use of this information. To enable tagged output, run a P4 command with the option –ztag:


     p4 –ztag changes –m1

... change 1471

... time 1461319056

... user sknop

... client sknop.main

... status submitted

... changeType restricted

... path //depot/tests/...

... desc A simple change

 

To format the output, use the –F option to specify the template:

     p4 -ztag -F "Change: %change% Description: %desc%" changes -m1
Change: 1471 Description: A simple change The format can use the keys in the tagged output surrounded by the percent sign.

Typing this sequence every time gets tedious, of course, so we define an alias:

chg = -F "Change: %change% Description: %desc%" –ztag changes

 

Parameters

What if we want to refer to a parameter several times or change the order? Then we can use named parameters in the form $(parameter):

recent-changes $(max) = changes -m $(max)

A more interesting example might be to change the order of the parameters, for example with the p4 clone command:

       original-clone = clone
       clone $(p4port) $(path) $(dir) = -d $(dir) -u sknop clone -p $(p4port) -f $(path)

Now I can clone with the following command:

p4 clone perforce:1666 //path/to/project/... ~/local-repos/project

 

Chaining commands

Things get really interesting when you start chaining commands together using the && operator. For example:

delete-shelve $(cl) = shelve –d –c $(cl) && change –d $(cl)

Here we are using both parameters and chaining to create a convenient new command.

 

Input and Output

Sometimes we would like to use the output of one command in another command. We can do this by redirecting the output into a temporary variable and then read from the same variable again, using the redirect operators < and >. For example, to create a streams depot in a single command, we could create the following alias:

       new-stream-depot $(dpt) = depot -o -t stream $(dpt) > $(spec) &&
                                              depot -i < $(spec)

Keep in mind that the output of the first command is kept in memory in its entirety, and then passed on to the next command; i.e., this is not a pipe. If you list every single file on your server and redirect it to a local variable, for example, you might blow the memory of your local machine!

 

Parameter substitution

OK, here it gets funky. Using the helper command p4subst, we can rewrite the output of one command on the fly and provide it as output into another command. An example makes this easier to understand. In the new-stream-depot alias above we did not specify the stream depth (a new feature added in 2015.2). Let’s fix that now:

        new-streamdepth-depot $(dpt) $(depth) = depot -o -t stream $(dpt) > $(spec) &&
                          p4subst "//$(dpt)/1" "//$(dpt)/$(depth)" < $(spec) > $(spec2) &&
                          depot -i < $(spec2)

We pass the additional parameter $(depth) that we use to replace the default stream depth, save the spec in a variable and pass it to p4subst.

p4subst "regular expression" "literal" < input > output

This command takes two values, a regular expression, and a literal value, and replaces any instances of the regular expression in the input. This process is made even more useful because it expands my parameters first as in the example above. You use this alias in the following way:

p4 new-streamdepth-depot newname 1/2/3

or, even better:

p4 new-streamdepth-depot newname project/component/codeline/pre>

 

Some examples

Here are some more examples I found in our internal promotion wiki for the new alias feature.

 

I don’t like typing long words


   itg = integrate

   pop = populate

   rc = reconcile

   di = diff

 

I want to pretend I'm using git/subversion/etc

checkout = sync
commit = submit
purge = clean
stash = shelve
blame = annotate
stash-list = changes -s shelved
pull = fetch –t -r origin

 

I alias my own aliases

co = checkout
ci = commit

 

More complex examples

The special variables $(EQ), $(LT) and $(GT) expand to =, < and >, respectively. So with this alias:

cherryPick $(cl) $(s) $(t)= itg //depot/$(s)/...@$(EQ)$(cl) //depot/$(t)/...

(making use of the itg=integrate alias), I can write:

p4 cherry-pick-change 1015978 p15.2 main

which gets turned into:

p4 integrate //depot/p15.2/...@1015978,1015978 //depot/main/...

There are some more examples in the workspace. Have a look here!

 

There are quite a few more hacks and examples which could turn this post into a whole book, but I’ll reserve those for future posts. If you come up with something clever you’d like to share, drop me a note or send me a tweet at @p4sven. There is a whole host of other goodies in the new 2016.1 release, so why don’t you have a look at the release notes? I’ll be writing about some of these features in the coming weeks.

Happy hacking!