July 12, 2010

p4 grep


The new Perforce server release 2010.1 has just been released; you might have seen the announcements on our website. There have been many internal improvements, most noteworthy for me has been the addition of 'move -f', which Sam Stafford wrote about in a recent post here.

There is also a new feature many Perforce users have been asking for for a long time: the ability to search through the content of files on the server. This new feature is called 'p4 grep', named after the well-known tool grep of Unix lore.

'p4 grep' allows users to use simple file searches as well as regular expressions to search through file contents of head as well as earlier revisions of files stored on the server. While not every single option of a standard grep is supported, the most important options are available. Here is the syntax of the command according to 'p4 help grep':

p4 grep [ -a -i -n -v -A after -B before -C context -l -L -t -s -F -G ] -e pattern file[revRange]...

Most users of the standard grep will be used to the syntax 'grep pattern files...', but the format 'grep -e pattern files...' is a valid alternative syntax useful if the pattern contains a '-' character. For 'p4 grep' the '-e pattern' syntax was chosen to easily distinguish the pattern from the file arguments.

Usage examples

Instead of explaining every option, which you might know from the standard grep already (or can look up in the documentation), I would like to demonstrate some use cases to show how 'p4 grep' could be used.

Fixed strings

I am looking for the string 'compile_settings' in Jam's source code:

p4 grep -e compile_settings Jam/MAIN/src/...

This will return all lines of all files of the head revision that contain this phrase, including the revision number of each file:

//depot/Jam/MAIN/src/compile.c#35: *    compile_settings() - compile the "on =" (set variable on exec) statement
//depot/Jam/MAIN/src/compile.c#35: * compile_settings() - compile the "on =" (set variable on exec) statement
//depot/Jam/MAIN/src/compile.c#35:compile_settings( parse, args )
//depot/Jam/MAIN/src/compile.h#10:void compile_settings();
//depot/Jam/MAIN/src/jamgram.c#21:# define pset1( l,p,a )      parse_make( compile_settings,p,P0,S0,S0,l,L0,a )
//depot/Jam/MAIN/src/jamgram.y#14:# define pset1( l,p,a )      parse_make( compile_settings,p,P0,S0,S0,l,L0,a )
//depot/Jam/MAIN/src/jamgram.yy#16:# define pset1( l,p,a )      parse_make( compile_settings,p,P0,S0,S0,l,L0,a )

'p4 grep' uses the same logic as 'p4 files' or 'p4 print': the file arguments can be adorned with a revision range. 'p4 grep' will then search the file with the highest available revision in that range, unless the option '-a' is used, in which case every revision in that range is considered.

This can be used as an alternative to 'p4 annotate'. When was compile_null()  introduced to Jam?

p4 grep -e compile_null -l -a Jam/MAIN/src/...


The '-l' option prints out files that have at least one match. The '-L' option prints out files that have no match anywhere in the file. So, to find out all header files that do not have the word 'copyright' in any spelling anywhere, use the following command:

p4 grep -e copyright -i -L Jam/MAIN/src/....h


Ironically, this includes the regexp.h file on which the regular expression algorithm used in 'p4 grep' is based. The option '-i' enables case-insensitive search.

To find out more details about 'p4 grep', please refer to the documentation. There is also an internal presentation I gave at Perforce a while ago. The PDF document of the presentation is located here.

Happy hacking.

Sven Erik