What is the relationship between workspace and working directory - perforce

I've been reading about Perforce but haven't found any comprehensive explanation of relationship between workspace and working directory, e.g. how files appear in working directory from workspace, how they are tracked, what inconsistencies are possible between workspace files and working directory files etc.
I come from git background, and so I'm looking for the description of workspace and working directory interaction similar to index and working directory interaction in git.

For comprehensive information, the full Perforce documentation is available online. But here's a basic summary of the terms and concepts:
Perforce is a client-server system. The server tracks changes to files. Developers perform modifications to files using copies of those files on their machines, arrange those modifications into units called changelists, and submit those changelists to the server when they are ready.
All information about files is stored on the server. A client, or workspace, is a set of configuration data about a single copy of versioned files stored on a developer's workstation. For each workspace, the server keeps track of: which files are currently sync'd to that workspace, which pending changelists are being constructed, which user is using those files, in which directory on which computer the workspace resides, etc.
Getting a copy of versioned files into your workspace is called sync; submitting a new changelist with new file versions is called submit. As other users submit modifications of files, your workspace gradually becomes out of date; to bring it up to date you issue the sync command, possibly followed by the resolve command to merge newly-submitted changes to files you have been editing.
There isn't an exact analog of the git index construct. Modified files are copied from the developer's workspace on their workstation to the server by the submit command, and then are stored permanently in the server's archives. A somewhat different workflow is available in Perforce called a shelf. You can construct a changelist with modifications, and then use the shelve command to store that pending changelist on the server in shelved state. Pending and shelved changelists have several similarities to the way that git add allows you to assemble a commit prior to committing it, but there are also a number of differences, starting with the fact that Perforce tracks that information on the server, not in the client.

Perfore does not really have the concept of the "index/staging area" that Git does. Files only exist within the Perforce server (the depot) or in your local working directory.
The workspace is just a bundle of configuration data that tells Perforce what files to put where in your local environment.
It is effectively a "binding" that specifies what files to select from the depot and where to place them in your working directory. This flexibility can be incredibly useful in some circumstances, but it is also an extra level of indirection compared to other VCS's such as Git/Mercurial/Subversion.
If you look at the contents of a workspace definition you will see a "Root:" section that points to a location on your local machine, and a "View:" section that tells Perforce what files you want synced to that location.
The Perforce documentation is a bit confusing with regards to its terminology. In the docs I've seen, "Workspace" refers to BOTH the specific workspace definition that you create (which is a data structure held within the Perforce server) AND the local working directory that the workspace is bound to, fairly interchangably. This is because the whole point of a workspace is to bind to a specific local working directory.
Take a look at example 15 here: Managing files and changelists
The output of the p4 sync command shows that it is writing files to the C: drive. When you "retrieve files from the depot into your client workspace" that DOES actually mean that files get copied into your local working directory.

Let's take a workspace definition for example. The key fields for this explanation are Client, Root, and View, so I'll only show those for clarity:
Client: mysimpleclient
Root: /Users/johndough/myspecialproject
View:
//depot/foo/... //mysimpleclient/...
The Client field defines the name of the workspace. The Root field defines the root of the workspace on the local filesystem. The View field describes how files from the server will be mapped to your workspace files. (This adds some flexibility when compared to Git, but at the cost of a bit of a learning curve). I've used a very simple mapping here, but this could be a lot more complex.
Let's break down the View field. Let's say the server has a file //depot/foo/bar.txt.
When you sync (get latest revision) of this file, Perforce will use the view line to determine where the file lands on your filesystem.
Here is our view again:
//depot/foo/... //mysimpleclient/...
The left side is in depot syntax, the right side is in workspace syntax, and it always starts with //workspace_name. The "..." is a recursive wildcard (kind of like ** with globbing). You can mentally replace the workspace name with the value of the root, to make sense of this.
Remember our root is: /Users/johndough/myspecialproject
So, after replacing "//mysimpleclient" with that value we arrive to:
//depot/foo/... /Users/johndough/myspecialproject/...
Let's use that modified view line to figure out where bar.txt will end up:
//depot/foo/bar.txt /Users/johndough/myspecialproject/bar.txt
This is how it works when you pull files down. When you add new files, the mapping is read in reverse. Let's say you create a file /Users/johndough/myspecialproject/fred/file.txt
Our (mentally modified) view is:
//depot/foo/... /Users/johndough/myspecialproject/...
We interpret this in reverse. Concatenate the relative path of the new file with the root of the workspace:
/Users/johndough/myspecialproject/fred/file.txt
And then do the same for the left side:
//depot/foo/fred/file.txt
Putting it altogether:
//depot/foo/fred/file.txt /Users/johndough/myspecialproject/fred/file.txt
Hopefully this helps. The notion of workspaces is probably the most difficult aspect of getting started with Perforce. Happy coding!

Related

Perforce: How to mark for delete files present in depot but not in workspace?

We have a code base which is downloaded from internet (GitHub repository). Updating process is following:
p4 Checkout existing version
Download new version from internet and extract it over old version
p4 Revert unchanged files
p4 Submit changes
Problem with this approach is that files which are not present in downloaded repo (removed from GitHub repo) are still present in file system and considered as unchanged. Revert unchanged files will revert them back and keep in depot/workspace. This is particular problem for Java files since we compile by specify root folder. Remaining file is unreferenced in new source but you can't see it.
p4 clean has option -d
Deleted files: Find those files in the depot that do not exist in your workspace and add them to the workspace.
but I am looking for opposite
Find those files in the workspace that do not exist in your depot and delete them from the depot.
If I delete whole folder structure from file system, workspace goes out of sync.
How to find/mark for delete files which are not present in new folder structure?
This is my typically recommended workflow for this use case:
Start with an empty workspace
Extract the current version of the tree into the workspace
p4 flush to the revision you want to use as the base (if you've made no changes to this branch on the Perforce side, you can just use the default #head)
p4 reconcile to open all files for the appropriate action
p4 submit
To elaborate on step 3: the "base" should be whatever revision the two trees were last in sync at. If this is a one-way operation, it's always just the latest revision (which came directly from github). If you're making changes on both sides, you should have a separate branch on the Perforce side for your github imports, and only use it for imports; then do one-way merges from there into your development mainline so you can resolve differences with all the right history tracking.

Can I get files from "Depot" without a "Stream" in Perforce P4?

So I've been reading the helix-core documentation for the p4 command line tool because I cannot use the visual client on my current machine. I am trying to get a way to get the latest files from the local depot on the server, which stores the project me and my team are working on.
I have found the sync command but it requires a stream. I never had to define one when I set up the visual clients for the team or the server if I recall correctly and so if I had one I couldn't find it. The administration tool only shows me the depot like this: //depot/myFiles, which is the default local depot that is created when the server is created if I'm not mistaken. So I've been wondering if it's possible to just "get latest" like in the visual client without a stream or how I can find the stream this depot is using.
tl;dr: the thing you want to make is a "workspace", not a "stream". Run p4 client to create a workspace.
Depots come in two basic flavors in Perforce: stream and local (aka "classic"). The type of a depot is set when it's created by the Perforce admin. One server can have any number of depots.
In a stream depot, files are organized into streams, which by default take the form of top-level depot directories, e.g. //stream/main and //stream/rel1. Streams can be configured to represent files beyond what's in the actual depot directories, but in their simplest form each stream just corresponds exactly to a directory in the depot, including one mainline stream and usually many other streams that are branched from the mainline. Every file in a stream depot is inside a stream. You can run the p4 streams command to see a list of all the streams.
In a local depot, there are no streams. You can add any file anywhere. Usually files are organized into parallel top level directories that are branched from each other, e.g. //local/main and //local/rel1, but there are no guard rails that steer you toward this.
In any kind of depot, you need to create a client workspace to sync and submit files. Each workspace has a client view which creates a mapping between depot files and workspace files; the client view takes depot files and puts them into your workspace when you sync, and it takes workspace files and puts them into the depot when you submit. Each workspace is unique to a particular directory on a particular client machine (the client root) -- you must create a new workspace for each local machine you do work on!
In a stream depot, when you create a workspace, you specify the Stream that you're going to work on. A client view is generated for you automatically that maps your workspace root to the files in the stream. You are not allowed to modify this view manually; if you want to change the view, you need to change the stream, and this will automatically update the views of all clients associated with that stream (so one stream may have many clients, but they will always share a consistent view -- the main function of streams is to centralize client view management).
In a local depot, when you create a workspace, you define a View yourself. By default, when you create a workspace on a server that has a single local depot, the client view maps the entire depot to the workspace root. You can edit the View yourself to map arbitrary paths in the depot to arbitrary paths within your workspace, so you have complete control over which depot files you sync and where each one goes.
To create a client workspace from the command line, run:
p4 client
This will open an editor that contains the client spec. Edit the Stream or View field appropriately. Note that the default name of the client workspace is the hostname of your client machine that it lives on; if you want to change this, run p4 set P4CLIENT=your-client-name before running p4 client. Save the client spec, exit the editor, and you'll see a message like "client saved".
Now you can sync:
p4 sync
This will use your current client spec (the one you've just defined) to sync files from the depot into your workspace. You only need to create the client spec the first time you set up a new client machine, but you can run p4 client again at any time to modify it.

How can I synchronize(submit) my local folder with depot, when I have lots of redundant files deleted manually from workspace,

I have never used P4 version control system before, and just come across with following problem:
I was submitted a project to server with lots of redundant files and have been working on the project actively. Now I have my project working and clean, and want to synchronize with depot. The problem is that I have deleted lots of files manually in windows file explorer(from my workspace),ignoring the rules of p4(mark for deletion, submit etc.).
How can I synchronize my project with depot? With another word, how can I delete files from depot that I have manually deleted from local folder, which are not shown in "workspace" tab.
Run the command:
p4 reconcile
This will automatically scan your entire workspace for added/deleted/modified/renamed files and open them for the appropriate actions. Once you've run reconcile you can just p4 submit as normal, and everything you did in your workspace should get submitted to the depot.
If you're using P4V, I think there's a "Reconcile..." menu command that will do something similar.

How can I query Perforce for a list of users who have workspaces that reference a particular file in the depot?

I would like to query my Perforce server to get a list of all users who have an active workspace whose view specification references a given file in the depot.
For example, given the file //root/folder/file.txt this command should return a list of the users who have an active workspace whose view specification references //root/folder/file.txt
Alternatively the command could just return the workspaces that reference the file, and then it should be straight forward to get the list of owners of those workspaces.
First you'll get the workspaces, and then you can run through the list of workspaces to get the owner.
To get the workspaces you will need to loop over every workspace in your server and run(assuming your filename from the question):
p4 files //root/folder/file.txt#<workspace name>
If you get a 'no such files' error, then the workspace doesn't have any version of that file synced. For all of the workspaces that do have the file, you can then look up the owner in the spec.
Note that this query is checking to see if the workspace has the file synced, not just mapped. My general assumption is if they map it and don't sync it, the file is nearly as good as unmapped.

Perforce cmd line option to populate workspace

I am new to Perforce and have some experience using ClearCase earlier. I am using a Windows XP client and trying to set up my perforce client/workspace.
The Perforce view I have has mappings of type:
//depot/path/to/folder/... //my_workspace/depot/path/to/folder/...
However, I have not attempted the "Get latest revision" action (in p4v) for this workspace. That means, I don't have a local copy of the folder in question.
My question is: How do I populate the workspace with contents of the folder from the command line when the folder isn't present in the workspace ? The manual for p4 sync talks about getting a certain revision when the file is present in the workspace.
In terms of ClearCase, when the config spec for a snapshot view is having loadrules too, then cleartool can be told to pick the config spec from a text file and also load the contents of the view. I am trying to achieve a similar thing for Perforce.
Thanks in advance,
Parag Doke
Running the sync command will populate the workspace. If a file or folder isn't already present, it will be created during the sync operation.
With no additional flags specified, p4 sync will populate your workspace with the latest contents at the time the command is started.

Resources