Perforce and submodules - perforce

At work we are using Perforce and I wonder if it's possible to do submodules with it with versioning.
For example I have library A used by projects B and C.
I want to make it so that when I get revision of B I also get A in subfolder:
B
---=> A(v1)
Same goes for project C, but it would need newer version of library.
C
---=> A(v1.2)
I know this kind of thing is possible with Git, but could not find anything on it for Perforce.
Thanks,
Leonty

Perforce really handles this sort of thing with views and paths. These let you assemble the right set of files to put into a workspace (or branch or label). Since a Perforce repository can contain all of the components or modules for all your products, you just select which ones you want in a working data set. You don't need the submodule (or SVN external) concept to pull in data from another repository.
You can use template workspaces to make sure that developers get the right set of files to work on. You can be a little more rigorous and write some custom tools (possibly in the Perforce broker) to provide some structure.
The closest equivalent to using submodules is found in Perforce streams, where the paths define what goes into a stream. Stream paths are inherited by child streams. This isn't a direct equivalent though.

Related

Organizing common files in a separate area in depot

Typically, we have a depot root for every different product that we work on. For e.g.:
//products/productX
/productY
As the common files in the 2 products increase, I would like to put them into a top level folder of it's own
//products/productX
/productY
/common
Now to ensure that this works for all the users who have existing workspace, we would need to update all their workspaces. Is there an alternative? Can we put some markers in the depot to create a link it to a different folder? Any other option?
What you're describing is essentially the reason that streams were created -- the idea of a stream is that you definition the structure of a codeline in one place (e.g. "product X lives in //products/productX"), multiple people base their workspaces on that, and when you change it (e.g. "product X lives in //products/productX + //products/common), every workspace based on that definition updates automatically.
So if you're using streams, all you need to do is update the stream definitions that need to include the new //products/common directory. Easy!
If you're using "classic" workspaces, users who are using the default //products/... mapping will get the common directory automatically regardless. For users with custom views, my suggestion would be to alert them of the refactor and then let them make their own adjustments as appropriate; if they're familiar enough with Perforce to have built a custom client view, they may not appreciate having it changed underneath them.

Perforce streams, exclude files from merge/copy

I have following perforce streams structure: main branch and 2 development branches linked to it dev_v1 and dev_v2. Both development streams has some build control files where version specific variables are located. Any change in these files will be reflected in Perforce Streams Graph and the system will ask me to merge them into main and then from main into other development branch.
How to exclude specific set of files in Perforce so that in case of any change the system will no show any difference between streams and will not ask to merge/copy them.
If those build files should never be integrated you should set that path in the stream view to be 'isolate' instead of public. That will add the files to client views for that stream, but will exclude them from any generate branch maps. That will cause them to fall out of the integration calculation and Perforce will stop trying to integrate them.
Isolate was specifically put in streams to handle build files that are unique to each stream, so this is the perfect use.
When you merge you can select which change lists you want to include in the merge, and which you want to exclude. If you are using P4V when you get into the merge window you can choose which changelists to merge into the other code line. Most of our items are set up as streams...if you are a using a standard depot the functionality to should be similar...if you have troubles let me know I can set up another depot on my dev server.

TFS Best way to handle branches and project references

I have the following TFS configuration
Root\
Proj1\
App1\
...
App2\
...
Proj2\
Lib1\
...
Lib2\
...
App1 and App2 both have project references to Lib1 and Lib2.
App1 does not reference App2, and Lib1 does not reference Lib2.
Now, I want to make changes to Lib1... but I want to branch it because the changes are drastic. These changes shouldn't require changes in either app1 or app2.
I created a branch Lib1Branch1 in TFS... but App1 and App2 both still reference Lib1 rather than lib1branch1... I don't want to manually re-reference the branch in each App (In actuality I have much more than just two).
When I used SVN, if I branched a project, and switched to that project, the local folders kept their original names and only the contents changed... thus building with one branch of the lib vs. building with the other only required that I switch branches and do a get-all... how do I get similar behavior using TFS?
I think you have a misunderstanding.
A Project is a self contained piece which is part of a larger thing called a solution. For example, a single class library is one project. It may reference other projects.
There are several ways to do branching. Minor branches might just require branching a particular project within the solution (such as Lib1) while major changes might require branching the entire solution.
It sounds like what you need to do is change your TFS structure slightly, then branch the entire thing. For example, the folder structure should probably be similar to the following:
Root
\1.0
\Web Apps
\App1
\App2
\Libraries
\Lib1
\Lib2
Then, when you branch, you take the entire 1.0 branch. That way all references are preserved between the two branches.

Instancing files in Perforce across multiple locations

Maybe some Perforce gurus could provide some advice.
We have a depot, with a setting.xml file in central folder:
///depot/central/config/setting.xml
and would like it to be instanced in several locations, like:
///depot/projectA/tool1/config/setting.xml
///depot/customerB/tool2/config/setting.xml
The benefit is for maintenance. the setting.xml file only has to be updated once in //depot/central, then all files in the other places get updated as well, so we don't have to get into each place, duplicate it again and again.
AlienBrain has a feature called 'shortcuts', does Perforce have something similar?
We've tried use the OS' symbolic links feature, but it didn't behave the way expected -- cloned files still need to be checked-out first, then check them in again -- this makes the cloned files own their own revisions against the original one.
It's better to just keep the original and cloned files have the same revisions. so if submitting a new revision to setting.xml(5/5)(which makes it to be setting.xml(6/6)), the cloned files as this point still remains setting.xml(5/6). Thus, people on projectA & customerB can simply sync to the latest version.
Thanks.
You can use the Perforce client spec to map files from the depot into your workspaces, which should do almost exactly what you're looking for.
For example, your client spec for tool 1 would be something like:
//depot/projectA/tool1/... //workspace_for_tool1/...
//depot/central/config/setting.xml //workspace_for_tool1/config/setting.xml
And your client spec for tool 2 would be something like:
//depot/customerB/tool2/... //workspace_for_tool2/...
//depot/central/config/setting.xml //workspace_for_tool2/config/setting.xml
The main downside of this approach is that you need to make this change in every client spec, and you need some infrastructure dedicated to propagating client specs to new workspaces.

How can I have a post-commit hook that is only called when commits are made to TRUNK?

I have a repository that has the following directories:
branches
tags
trunk
The trunk directory contains the main line of development. I have created a post-commit hook script for the repository that updates a working copy (of trunk) when a user commits back to repository.
It looks something like this:
/usr/bin/svn update /path/to/a/working/copy
I've just created a branch of the code as I'm about to start some major changes but noticed that when I commit my changes to branch it calls the post-commit hook and updates the working copy (copy of trunk).
Is there a way I can modify either my post-commit hook script or a setting that I can make that would only update the working copy if the commit was made to the trunk directory and not any other directory?
As you can see in this documentation, parameters are passed to the post-commit script.
The repository passes two arguments to this program: the path to the repository, and the new revision number that was created.
The post-commit hook could be any program of any type : a bash script, a C program, a python script...What happens is that the shell launches this program, with the two parameters.
You can find a list of interesting scripts here. A good beginning would be this python script, which uses the python svn libs.
Please note that the path provided is not the same as the path to the file that you are checking in (see Paul's answer). But using this information with the revnum should help you to get the list of the changes, from which you can determine if operations have been done on trunk or not.
In addition to the answer from Bishiboosh, it is worth noting that the hooks can be any program. That is, if you wanted to, you could write the program in C. The parameters that are passed are described in the doc.
For a good repository of scripts to get inspiration from, have a look at the subversion tools page. In general, if you want to do some conditional processing based on the contents of the transaction, and you do, since you only want to process if the files are in trunk, then it will be easiest to use Python, since that comes with a bunch of tools to examine the transactions. This script is a good place to start looking for inspiration.
Note, that the path to the parameter, is not the same as the path to the file that you are checking in. You could have multiple files in the checkin after all… What you are passed is the location of the repository, and the revision of the change. Using these two pieces of information you can get the information about the change from the repository, and use that information to decide whether to perform an action or not in the post-commit hook.
Here is another example (in Perl) That explicitly checks the path of the files in the checkin. This is a much more complicated script, but most likely the salient parts can be ripped out and re-used.

Resources