Perforce Software p4ideax | Intelligent symbolic links in the depot
'via Blog this'
I have also been looking for this "symlinks in depot".
It is possible that streams may do this - I may not totally grok streams yet (not helped by our IT forbidding us from using streams in P4, and highly discouraging branching (p4 branching support, is of course, primitive)). But based on what I have seen so far, streams are much more complicated than what I want to do with symlinks/
Here is one of the use cases where I want to use depot side symlinks:
I want to merge two directories that have diverged versions of files.
Unfortunately, they are NOT branches. The user who created them did not understand branching. Instead, she copied the files outside perforce, and then added the copy as a separate set of files that, from Perforce's point of view, are totally independent, unrelated. (Fixing that is a separate topic.) Call this a "fake branch". (E.g. think about cp -R from to creating a fake branch of a directory tree - logically a branch, just one that your version control tool may not be able to figure out.)
Unfortunately^2 they are binary files that I can merge, but must do so by hand. Painful. Slow. I can't get the merge done all in one day.
So here is what I want to do: as I merge the several hundred files in the fake branch directory
- let's call the original
and the "fake branch"
I must leave the two directories GoodDir and FakeBranchDir around.
But as I merge files GoodDir/file1#666 and FakeBranchDir/file1#1 into GoodDir/file1#667,
I want to make FakeBranchDir/file1#2 into a "depot symlink" to GoodDir/file1
so thereafter anyone attempting to work with FakeBranchDir/file1 will get whatever the latest version of GoodDir/file1 is.
And I will do this one by one for all of the files.
(By the way, I can do this because I know the dependencies. I.e. I can do continuous partial integration (merging, reconciliation).
Sometimes I have to do several files together atomically, but not the entire directory.)
When all of the files are merged, so that every file in FakeBranchDir/fileN is a "depot symlink" to GoodDir/fileN,
I can do the following:
* remove all FakeBranchDir/fileN depot symlinks, and make DEPOT/c/d/FakeBranchDir a depot symlink to DEPOT/a/b/GoodDir
* potentially just plain remove FakeBranchDir completely, and stop the insanity of having unnecessary fake branches in the depot
Anyway... streams may do this, but they seem like overkill, plus IT has forbidden p4 streams. Heck, my team barely knows how to use branches - actually, I am strongly discouraged from using branches (but I am so used to branching...)
Lacking depot symlinks or other support, here is what I am doing:
+ Merging the files
+ Once merged, copying the files into BOTH GoodDir/file1 and FakeBranchDir/file1, etc.
+ hoping that nobody modifies the merged files separately, causing them to re-diverge.
+ unfortunately, not allowed to create a long-lived lock. Folks still want to edit in ther diverged directories
I have thought about using p4 branch mappings to accomplish the same thing as a "depot symlink", but that is a pain - I would have to edit the branch mapping every time a file GoodDir/fileK and FakeBranchDir/fileK were merged.
Basically, "depot symlinks" are just a way of allowing you to edit the branch mapping, without actually having to edit the mapping in a central place. They are a "distributed" view of the branch mappings.
Now, yes, I know: this creates a "fragile base class" problem. Somebody checking something into GoodDir/fileM might break FakeBranchDir/fileM (if it is a depot symlink), because the "context", the surrounding files, may break it in the FakeBranchDir context. Yes, I realize that we really need to be using branches here (not p4's primitive branching, but some sort of branching for a partial subset of the depot - which may be what p4 streams are trying to do.). So that when somebody checks into GoodDir/fileM, FakeBranchDir/fileM can detect that it needs to be updated, but is not automatically updated until you have tested it in the FakeBranchDir context.
(Hmm, what this really means is that FakeBranchDir/fileM#2 may be a depot symlink to GoodDir/fileM (after some base revision)
FakeBranchDir/fileM#2-->GoodDir/fileM(#latest,validated=1011). Using notation to indicate that we are supposed to link to the latest, but at the last time of checkin that value was GoodDir/fileM#1011; as opposed to linking to FakeBranchDir/fileM#2-->GoodDir/fileM#1011, which would be a depot symlink, but one that is not normally updated by default.
I.e,. a depot symlink really wants to be a branch. But it is a branch that you normally want to be encouraged to update as quickly as possible, perhaps by default, as opposed to having to do an explicut branch merge.)
But, these are dreams for my own VCS.
Just plain old depot symlinks, though, are a darn good first step.)