9/08/2012

09-08-12 - p4util

p4util is a replacement for p4.exe.

It does two major things differently that are important for me :

1. It fixes file names for you. The primary two fixes it does are :

1.A. De-mapping of substed or net used drives. eg. if you have c:\src as your client root, and you map s:\ to c:\src , perforce can't handle any paths in s:\. p4util will take s:\ paths and convert them to c:\src.

1.B. Case fixing (p4 is so fucked up in this regard; the behavior of SVN software should not be affected by what my client and server are running on; there should just a setting for case sensitive or not, and both ways should work on all OS'es). Anyhoo, p4util checks if the depot has a file name that is the same except for case and fixes it for you (so that the broken situation of Windows client and UNIX server works passably). eg. if your depot has "Stuff" in it and you p4 edit "stuff" it will fail, but p4util will succeed.

2. It can pick up its working dir from file names.

P4 has this nice "P4CONFIG" feature in which you can set up config files to have different servers for different dirs. I use it to run a home p4 server on one source tree and use the RAD p4 server on another source tree.

That's all well and good, but p4.exe picks up the P4CONFIG from the working dir it is run in. That's dumb. When I do a

p4 edit c:\rad\stuff.c
clearly you should use the P4CONFIG from c:\rad to do that, not the one from whatever cwd I happen to be in. So p4util can (optionally) do that.

Here it is, at cbloom.com : p4util.exe (zip)

I also just added a special command to create a summary of how your client differs from the depot. The main part of snapshot is to do "p4 changes -s pending" and then describe all those changelists. (but just doing p4 opened and p4 diff works pretty well too).

TODO : make a full snapshot/recover that saves copies of files that differ so you can fully save state and restore to it, even with files at weird sync points or different from depot.


ADDENDUM :

BTW before I wrote p4util I was using another program I wrote called "makedesubst". makedesubst writes a temp bat called desubst.bat which you can use to cd to the non-substed version of your path.


cddesubst.bat :

@makedesubst
@s:\desubst.bat

p4.bat :

@echo off
pushd
call cddesubst
"C:\Program Files\Perforce\p4.exe" %*
popd

So that worked for the problem of your cwd being on a substed drive, but didn't fix any other problems, so I went for the full p4util solution.

makedesubst is a very trivial program which just runs GetFinalPathNameByHandle on the current directory :

{
    HANDLE f = CreateFile(GetCurDir().CStr(),
        FILE_READ_ATTRIBUTES | STANDARD_RIGHTS_READ
        ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0);
    if ( f == INVALID_HANDLE_VALUE )
    {
        lprintf("ERROR : CreateFile\n");
        return 10;
    }

    char buffer[1024];
    DWORD bufSize = ARRAY_SIZE(buffer);
    DWORD ret = CALL_KERNEL32(GetFinalPathNameByHandleA)(f,buffer,bufSize,0);

    CloseHandle(f);

    if ( ret >= bufSize )
    {
        lprintf("ERROR : GetFinalPathNameByHandleA\n");
        return 10;
    }

    char * pnorm = buffer;
    stripresameadvance(&pnorm,"\\\\?\\");
                    
    String out = StringPrintf("cdd %s\n",pnorm);
                
    bool ok2 = WriteWholeFile("s:\\desubst.bat",out.CStr(),out.Length());
    if ( ! ok2 )
    {
        lprintf("ERROR : WriteWholeFile\n");
        return 10;
    }

    return 0;
}
which uses some cblib stuff, but replacing it with non-cb stuff should be obvious.

(it is possible to change the CWD of your parent process, but it's ugly, so I took the easy way out of writing a bat)

No comments:

old rants