To simplify the branching process, allow automation and remove the errors likely from manually branching, I'd like the whole process to be scripted. The P4 command allows us to do this, but there are complications as it requires user input via the specification forms for most of its commands. You can direct it to read the input from a file, but that's not much help when you want to use variables to specify branch names etc.
Generating Specification Forms on the Fly
My solution was to create a simple console app to generate spefication forms based on input parameters. The variables in the script go into the generator which stores them as files, which P4 can use as input. It's not terribly elegant, but it's efficient and I haven't found any other solutions out there. The code is on CodePlex here: Generate Perforce Specification Form
Using the console app, it's easy to take the manual steps from Branching with Perforce
and script them for automation. In this case, I'm expecting branching to be an occassional job so the purpose of scripting it is to reduce the possibility of error and simplify the branching process for anyone who needs to do it and doesn't want to trawl through these blogs.
With this in mind, the script is a Windows batch file (the full script is BranchWorkspace.bat
in the Samples directory of the CodePlex source) rather than a build task. It should be straightforward to read, but I'll dissect it here to show how the commands fit in with the manual process.
Firstly the batch file sets up parameters for all the variables we'll use - branch name, branch master workspace name, views etc. Then it follows the same order as the manual process, generating the specification forms where needed, then invoking the P4 command and telling it to read from the spec form.
1. Create the branch view
::generate spec form for the branch:
GenerateP4SpecForm "WRITE" "%branchSpecPath%" "|" "Branch: %branchName%|Owner: elton.stoneman|Description: Created by elton.stoneman.|Options: unlocked|View: %mainView% %branchView%"
The console app takes parameters telling it where to create the spec form, how the form options are separated (I use a pipe as there are colons in the options), and then the pipe-separated option list.
What goes into the list depends on the type of spec form P4 wants; there are samples in the CodePlex source, or you can copy and paste from a real spec form, or many of the commands take a -o parameter so you can output an existing spec form and use that as the basis.
::create the branch view:
p4 branch -i <%branchSpecPath%
- the branch view is created and we pass the spec form path to P4 so there's no user intervention.
2. Create the master workspace
As before, generate the relevant spec form and pass it into P4:
::generate spec form for the branch master workspace:
GenerateP4SpecForm "WRITE" "%branchClientSpecPath%" "|" "Client: %branchClient%|Owner: elton.stoneman|Host: myHost|Description: Created by elton.stoneman.|Root: %branchClientRoot%|Options: noallwrite noclobber nocompress unlocked nomodtime normdir|SubmitOptions: submitunchanged|LineEnd: local|View: %branchView% %branchClientView%"
::create branch workspace:
p4 client -i <%branchClientSpecPath%
3. Flag files to be branched
No spec form needed here, but the batch file allows you to branch from the current revisions or from a specified label:
::integrate the branch back to main - branch to label if provided:
IF "%label%"==" " p4 -c%branchClient% integrate -b %branchName%
IF NOT "%label%"==" " p4 -c%branchClient% integrate -b %branchName% @%label%
4. Submit the change list
This is a bit different as the submit command launches a spec form listing the files to be submitted, and requires you to add a description. We can't generate the spec form here, as we'll lose the file list, so instead we output the file list first:
::get a list of the changes (required for Submit):
p4 -c%branchClient% change -o >%changePath%
- and then use the UPDATE mode of the console app to set the description (P4 always uses the same text for the default description):
IF "%label%"==" " GenerateP4SpecForm "UPDATE" "%changePath%" "<enter description here>" "MASTER created from branch: %branchName%"
IF NOT "%label%"==" " GenerateP4SpecForm "UPDATE" "%changePath%" "<enter description here>" "MASTER created from branch: %branchName%, label: %label%"
This way we get the full change list from Perforce and add in our description (in this case, specifying the branch view and label used to get the files). Now we submit using the updated change list:
::submit to create branch in depot:
p4 -c%branchClient% submit -i <%changePath%
And the branch is complete and populated.
Note, the sample batch file leaves the generated spec forms in place, in case of any issues. It's a simple change to make the script delete them at the end.