April 13, 2015

Remotes Made Simple

Media & Entertainment

Remember how the simplest thing we did early in this series of blogs was create a local repository? It’s been a while, so to refresh your memory we initialized a server, created a file, reconciled our work, and submitted it.

The whole point was to show how simple it is to create a new project using the DVCS features in Perforce Helix. DVCS makes it easy to explore new ideas and tinker around without worrying about where the project files might ultimately be stored on some official, company server.

But what if the new project takes off? What if it turns out to be a great idea that needs to get into production as soon as possible? That code “lives” only on the developer’s local machine, which doesn’t do others any good. So today we’re going to see how to take such a local repository and push it to a shared server where others can access it.

If you’re at all familiar with Git or Mercurial (Hg), you will recognize that a shared server is established by creating a remote. A remote is nothing more than a “pointer” to a shared location from which code may be fetched and pushed, and the default remote is named “origin” for sake of reference. Armed with those facts, let’s take a look at a sample file—unimaginatively named “origin”—which may be used to define the default, origin remote:

[email protected]:~/newProject$ cat origin
# A Perforce Remote Specification.
#  RemoteID:    The remote identifier.
#  Address:     The P4PORT used by the remote server.
#  Owner:       The user who created this remote.
#  Options:     Remote options: [un]locked, [no]compress.
#  Update:      The date this specification was last modified.
#  Access:      The date of the last 'push/fetch' on this remote.
#  Description: A short description of the remote server (optional).
#  LastFetch:   The last changelist that was fetched.
#  LastPush:    The last changelist that was pushed.
#  DepotMap:    Lines to map local files to remote files.
#               See 'p4 help remote' for detailed information.
RemoteID:       origin
Address:        1666
Owner:          sysop
Options:        unlocked nocompress
Update:         2015/03/30 15:23:37
Description:         Created by sysop.
LastFetch:      default
LastPush:       default
DepotMap:       //stream/main/... //depot/newProject/...

Long-time users will recognize this sort of syntax from other files used by Perforce Helix. Others shouldn’t be overwhelmed: simply executing the “p4 remote” command with a name for a new remote will invoke your system’s editor with all the basic defaults in place.[1] In fact, I initially created the above text file using the following command:

[email protected]:~/newProject$ p4 remote -o origin >origin

The “-o” argument dumped the resulting “template” to standard output, which allowed me to invoke my editor and customize it as it appears above. Without that argument (and the redirect), the command would invoke the editor and create the new remote directly.

For my purposes, I had to make but two changes in the file: (1) the address, which I set to port 1666, and (2) the mapping at the bottom. The mapping is the standarddepot-mapping syntax, which tells the repository that its origin on the server should be at “//depot/newProject”“//depot/newProject”.[2] Armed with that text file I can execute the following command:

[email protected]:~/newProject$ p4 remote -i <origin

I could have done this more directly in a single command, but it’s worth highlighting how the remote command interacts with standard input/output because this makes it possible to script all kinds of scenarios. I can subsequently verify my new remote was created with the following command:

[email protected]:~/newProject$ p4 remotes
origin localhost:1666 'Created by sysop. '

That command lists all the remotes, which makes it possible to interact with a multitude of servers. In fact, remotes are how a local repository cloned from a shared server “knows” how to fetch subsequent changes: the clone command creates the default remote as part of its operation. Anyway, now that our remote is defined, let’s the push command:

[email protected]:~/newProject$ p4 push
7 change(s) containing a total of 11 file revision(s) were successfully pushed.

And that’s all there is to it. All my local work is now stored on the shared server where anyone with the appropriate permissions can get at it. A couple of final comments are in order, first of which is a note to server admins: don’t panic. The ability to push (or fetch) code to a server is not enabled by default. The new DVCS features involve three server configuration settings described as follows:

SettingWhat it Does
server.allowfetchControls whether changes may be fetched.
server.allowpushControls whether changes may be pushed.
server.allowrewriteControls whether submitted changes may be overwritten

Documentation for the values of these (and all other) server settings may be found using the “p4 help configurables” command. Further, a server’s configuration settings may be shown using the “configure show” command and a given setting’s value may be set with the “configure set” command. For sake of reference, I set my server’s push and fetch settings to a value of two for purposes of this blog with the following two commands:

[email protected]:~/newProject$ p4 -p p4demo:1666 configure set
[email protected]:~/newProject$ p4 -p p4demo:1666 configure set

There’s more you can do with fetch and push, but those will have to wait for another article. In the meantime, go forth and push the best of your work to the rest of the world.


[1] The editor invoked depends upon the P4EDITOR setting, which is documented here.

[2] The “p4 init” command creates a single, main stream by default, which explains the “//stream/main/…” part of the mapping on the left.

All Perforce Version Management & Collaboration Products Are Free for 20 Users.