October 3, 2011

P4Sandbox's First Submit

Have no idea what "P4Sandbox" is? Watch our User Conference presentation.

A couple weeks ago, I ran an experiment with P4Sandbox to see if it really worked. Could I work disconnected from the office for several days? Could I create one task branch for each bug fix? Could I copy my work back to the central server when I reconnected? Could I copy up several small, focused, changelists, one for each bug fix? After five days and twice as many bugs fixed, the answer to all questions is: yes. Before I said goodbye to the office network, I created a P4Sandbox server on my laptop computer. I copied into it all of P4Sandbox's source code and test suite. I also copied several jobs to a text file: this would be my to-do list. I then unplugged from the network, and proceeded to live on my laptop for the next five days.

$ p4sandbox init Perforce sandbox broker starting on localhost:1666 ...
$ p4 remote -p perforce:1666
$ p4 integ //remote/depot/p11.1/p4-sandbox/src/... //streams/mirror/src/... Copying 307 files from '//remote/depot/p11.1/p4-sandbox/src/...' to '//streams/mirror/src/...'.
$ p4 integ //remote/depot/p11.1/p4-sandbox/test/... //streams/mirror/test/... Copying 104 files from '//remote/depot/p11.1/p4-sandbox/test/...' to '//streams/mirror/test/...'.
$ p4 job -o job048862 >> todo.txt

Since I would be working with P4Sandbox, which includes a new 'p4 status' command, I switched my client options to "allwrite", so that I could modify any file immediately without having to run 'p4 edit' first:

$ p4 client Client: zig-main-sand Owner: zig Options: allwrite noclobber compress unlocked nomodtime rmdir

As I started each new job, I created a task stream for it. Small, focused task streams made it possible later to copy small, focused changelists to the central server, rather than one Big Giant Changelist that fixed a dozen bugs and touched twice as many files.

$ p4 integ //streams/mirror/... //streams/job048862/...

These task streams were lightweight: they imported all of their files from their parent stream //streams/mirror. The only files branched into the task stream were the two or three files I changed while working on the task. I pored over the job, wrote a test case that exercised the bug. I checked in that test case, either via 'p4 add' or via 'p4 status -as' depending on whim:

$ p4 status -as //streams/local/test/sand_job048862.txt#1 - opened for add
$ p4 submit -d "test case for auto-shelve of untracked changes"

I worked on the code until the test passed. Whenever I got to a point where I wanted to save a snapshot of my work, or when I fixed the bug and was ready to move on, I used 'p4 status' to check out, then check in, all of the files that I touched:

$ p4 status -s //streams/job048862/src/cmd/cmd_integ.cpp#1 - opened for edit
$ p4 submit -d "fix for auto-shelve job048862"

'p4 status' is a new P4Sandbox command that scans for and lists any modified files. The -s flag checks them out for add, edit, or delete. Occasionally a bug stumped me. After enough head-scratching, I skipped it, then came back later after fixing something else. Task branches were perfect for this. I switched in-place from the stumping bug's stream to another bug's stream. I did not check in or shelve anything before switching tasks: P4Sandbox automatically shelved it when I switched out, and unshelved it when I switched back.

$ p4 switch job048863 Client zig-main-sand switched to //streams/job048863. //streams/mirror/src/cmd/cmd_integ.cpp#1 - replacing /Volumes/chibi/p11.1/p4-sandbox/cmd/cmd_integ.cpp //streams/job048862/test/sand_job048862.txt#1 - deleted as /Volumes/chibi/p11.1/p4-sandbox/test/sand_job048862.txt

After a while I accumulated quite a long list of task branches, each representing a bug fixed. Running 'p4 streams' to list them all became an unanticipated morale boost. Five days and many bug fixes later, I reconnected to the office network, and copied up my changes. Even though we had months of testing and a test suite that confirmed P4Sandbox worked, I still worried that something bad would happen when I copied to the central server. But as the great warrior-philosopher Jack Burton teaches us, "Hey, you never know until you try." So with an elevated heart rate, I typed...

$ p4 merge -rS //streams/job048862
$ p4 copy -S //streams/job048862 //streams/mirror/src/cmd/cmd_integ.cpp#1 - sync/integrate from //streams/job048862/src/cmd/cmd_integ.cpp#2 //streams/mirror/test/sand_job048862.txt#1 - sync/integrate from //streams/job048862/test/sand_job048862.txt#2
$ p4 submit -d "Auto-shelve before switch now shelves untracked changes, too."

It worked. The few files I changed, and the test script I added, were all copied from my P4Sandbox server to the central server, along with my change description. I repeated this sequence for each task stream. One task stream per job kept the changelists small and focused. P4Sandbox has become my primary VCS, whether I am in or away from the office. As of this writing, P4Sandbox has controlled its own source code for three weeks. P4Sandbox works. P4Sandbox is coming soon.