perlperforce

Just check if any output is coming after running "p4 sync -n", and not wait for the whole output


I have to run a p4 sync based on whether p4 sync -n has any output. But I want that as soon as the output of p4 sync -n has even 1 single line, p4 sync starts, and not wait for whole output of p4 sync -n.

So, let's say, I have the following lines:

p4 sync -n C:\farm\A...
p4 sync -n C:\farm\B...
p4 sync -n C:\farm\C...
p4 sync -n C:\farm\D...
p4 sync -n C:\farm\E...
p4 sync -n C:\farm\F..

.

and p4 sync -n C:\farm\B... starts giving output, then p4 sync should start there and then, and not wait for further output of p4 sync -n C:\farm\B...

How can this be done?


Solution

  • This is an XY problem. There's no benefit to running p4 sync -n and then immediately running p4 sync; presumably you're trying to avoid running an "expensive" sync command when there's nothing to sync, but if there's nothing to sync, then p4 sync -n and p4 sync are exactly equivalent in terms of performance (it's easy to profile this with the -Ztrack global flag if you want to prove it to yourself). Your script should just run p4 sync if the ultimate intent is to sync the workspace anyway.

    That said, answering the general question of how you ask "is there ANYTHING to sync" in the most efficient way possible, you want the -m1 flag, which will tell the server to return a maximum of 1 result and stop immediately. E.g.:

    C:\Perforce\test>p4 sync -n ...
    //stream/main/p4#1 - added as c:\Perforce\test\p4
    //stream/main/undo/foo#7 - added as c:\Perforce\test\undo\foo
    //stream/main/undo/itest/A1#5 - added as c:\Perforce\test\undo\itest\A1
    //stream/main/undo/p1/A#3 - added as c:\Perforce\test\undo\p1\A
    //stream/main/undo/p1/B#1 - added as c:\Perforce\test\undo\p1\B
    //stream/main/undo/tempobj#3 - added as c:\Perforce\test\undo\tempobj
    
    C:\Perforce\test>p4 sync -n -m1 ...
    //stream/main/p4#1 - added as c:\Perforce\test\p4
    

    Not only does this save you having to read and discard a bunch of output you don't want, it's faster on the back end because the server doesn't need to fetch all those database records only for you to discard them (and in the case of your script, of course, it will need to read them all over again when you run the actual sync, which is why you should just run the sync normally in the first place).