ClientUser::Diff( FileSys *, FileSys *, int, char *, Error * )

Diff two files, and display the results.

Virtual?

Yes

 

Class

ClientUser

 

Arguments

FileSys *f1

the first file to be diffed

 

FileSys *f2

the second file to be diffed

 

int doPage

should output be paged?

 

char *diffFlags

flags to diff routine

 

Error *e

an Error object

Returns

void

 

Notes

This method is used by p4 diff and to display diffs from an interactive p4 resolve. If no external diff program is specified, the diff is carried out with a Diff object (part of the Helix C/C++ API); otherwise, Diff() simply calls the specified external program.

As with Merge(), the external program is invoked with ClientUser::RunCmd().

If doPage is nonzero and the P4PAGER environment variable is set, the output is piped through the executable specified by P4PAGER.

See also

ClientUser::RunCmd()

Example

In its default implementation, this method is called by an application when p4 diff is run. For example:

p4 diff -dc file.c

results in a call to Diff() with the arguments:

Argument Value

f1

a temp file containing the head revision of depot file file.c

f2

the local workspace version of file file.c

doPage

0

diffFlag

c

e

a normal Error object

The diff is performed by creating a Diff object, giving it f1 and f2 as its inputs, and -c as its flag. The end result is sent to stdout. If either of the files is binary, the message “files differ” is printed instead.

Selecting the “d” option during an interactive p4 resolve also calls the Diff() method, with the doPage argument set to 1.

If the environment variable P4PAGER or PAGER is set, then setting doPage to 1 causes the diff output to be fed through the specified pager. If P4PAGER and PAGER are unset, dopage has no effect and the resolve routine displays the diff output normally.

To enable an application to override the default diff routine, create a subclass of ClientUser that overrides the Diff() method, and use this subclass in place of ClientUser.

As an example, suppose that you have a special diff program designed for handling binary files, and you want p4 diff to use it whenever asked to diff binary files (rather than display the default “files differ…​”).

Furthermore, you want to keep your current P4DIFF setting for the purpose of diffing text files, so you decide to use a new environment variable called P4DIFFBIN to reference the binary diff program. If P4DIFFBIN is set and one of the files is non-text, the P4DIFFBIN program is invoked as P4DIFF is in the default implementation. Otherwise, the default implementation is called.

Most of the following code is copied and pasted from the default implementation.

MyClientUser::Diff( FileSys *f1, FileSys *f2, int doPage, char *df, Error *e )
{
    const char *diff = enviro->Get( "P4DIFFBIN" );
    if ( diff && ( !f1->IsTextual() || !f2->IsTextual() ) ) // binary diff
    {
        if ( !df || !*df )
        {
            RunCmd( diff, 0, f1->Name(), f2->Name(), 0, pager, e );
        }
        else
        {
            StrBuf flags;
            flags.Set( "-", 1 );
            flags << df;
            RunCmd( diff, flags. Text(), f1->Name(), f2->Name(), 0, pager, e );
        }
    }
    else ClientUser::Diff( f1, f2, doPage, df, e );
}