Find a string in Perforce file without syncing

2020-07-13 07:50发布

问题:

Not sure if this is possible or not, but I figured I'd ask to see if anyone knows. Is it possible to find a file containing a string in a Perforce repository? Specifically, is it possible to do so without syncing the entire repository to a local directory first? (It's quite large - I don't think I'd have room even if I deleted lots of stuff - that's what the archive servers are for anyhow.)

There's any number of tools that can search through files in a local directory (I personally use Agent Ransack, but it's just one of many), but these will not search a remote Perforce directory, unless there's some (preferably free) tool I'm not aware of that has this capability, or maybe some hidden feature within Perforce itself?

回答1:

p4 grep is your friend. From the perforce blog

'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]...

See also, the manual page.

Update: Note that there is a limitation on the number of files that Perforce will search in a single p4 grep command. Presumably this is to help keep the load on the server down. This manifests as an error:

Grep revision limit exceeded (over 10000).

If you have sufficient perforce permissions, you can use p4 configure to increase the dm.grep.maxrevs setting from this default of 10K to something larger. e.g. to set to 1 million:

p4 configure set dm.grep.maxrevs=1M

If you do not have permission to change this, you can work around it by splitting the p4 grep up into multiple commands over the subdirectories. You may have need to split further into sub-subdirectories etc depending on your depot structure.

For example, this command can be used at a bash shell to search each subdirectory of //depot/trunk one at a time. Makes use of the p4 dirs command to obtain the list of subdirectories from the server.

for dir in $(p4 dirs //depot/trunk/*); do
  p4 grep -s -i -e the_search_string $dir/...
done


回答2:

Actually, solved this one myself. p4 grep indeed does the trick. Doc here. You have to carefully narrow it down before it'll work properly - on our server at least you have to get it down to < 10000 files. I also had to redirect the output to a file instead of printing it out in the console, adding > output.txt, because there's a limit of 4096 chars per line in the console and the file paths are quite long.



回答3:

It's not something you can do with the standard perforce tools. One helpful command might be p4 print but it's not really faster than syncing I would think.



回答4:

This is a big if but if you have access to the server you can run agent ransack on the perforce directory. Perforce stores all versioned files on disk, it's only the metadata that's in a database.



标签: perforce