Is there a way to swap files, and preserve history in perforce, in one step? - perforce

I have some files, like upgrade01.x and upgrade02.x, where the name defines some order. Due to external constraints, I must use this naming convention but I want so swap them, 01 become 02 and 02 become 01. I tried renaming update01.x to a temp name (without submitting it), then tried change update02.x to be update01.x but perforce doesn't let me do that.
I can submit the rename to something temporary, then rename one to the other, then the rename the temp, but is a monster pain. Also, the history looks really weird (but that might be unavoidable).
Is there a way to do this in one sane operation?

Doing the rename in two steps (rename both to intermediate names, then each back into the place of the other) might be the preferred option if you want the "identity" of each file to follow it to the new name (e.g. when you merge from other branches, you want merges to be remapped according to the new name rather than going to the old one).
If your priority is to have this happen in a single changelist, though, and you're not so concerned about whether the history preserves the notion of which file is which, I'd do it like this:
p4 copy upgrade01.x upgrade02.x
p4 copy upgrade02.x upgrade01.x
p4 submit
This will get you a nice neat little X in the revision graph (which I suspect is what you want), but not a true rename.
Merging to/from other branches will be a little tricky either way; if you go the true rename option, when you merge the rename to other branches you'll need to go change by change to repeat the process of renaming to something intermediate and then back (since the target branch will have the same constraint of not being able to rename onto something that is itself already open for rename). If you go the copy option, you'll need to manually specify which file to merge into which depending on what state each branch is in and whether there are outstanding changes requiring an actual merge.

Related

What's the difference between p4 duplicate and branching and merging?

So in perforce, we have p4 integrate p4 duplicate p4 copy and p4 branch what's the difference and when should I use which?
C:\Perforce\test>p4 help branch
branch -- Create, modify, or delete a branch view specification
...
You can use this command to (optionally) create a branch spec for later use with copy, integrate, merge, and/or populate. Note that all of those commands can also take an on-the-fly mapping in the form of two file paths, and if you're using streams you don't use branch specs because the mapping is generated automatically based on the parent and child stream.
C:\Perforce\test>p4 help copy
copy -- Copy one set of files to another
...
Opens the target files in such a way as to create new head revisions that are identical to those of the source files. (This may in some cases overwrite changes in the target -- if you're using streams, there are guards on copy to help prevent this, but otherwise you should always use integrate unless you're absolutely certain that you want to overwrite the target.)
C:\Perforce\test>p4 help integrate
integrate -- Integrate one set of files into another
...
Opens the target files (and schedules resolves) in such a way as to create new head revisions that combine all outstanding changes from the source with existing changes in the target. Actually performing the merges is done via the resolve command prior to submit.
C:\Perforce\test>p4 help duplicate
duplicate -- duplicate revisions with integration history (unsupported)
...
Like it says, unsupported. This has specific use cases that you will hopefully never need to discover.

Perforce submit edited source file and branch/integrate/merge/copy from same source file in one changelist

Suppose we have a single text file in 2 branches:
//depot/work/branch1/file.txt
//depot/work/branch2/file.txt
We also have a central source file here that both branches depend on.
//depot/work/ImportantFile.txt
I make local edits to ImportantFile.txt and branch1/file.txt, but I also want to duplicate those edits to branch2/file.txt because ImportantFile.txt now expects all branches of file.txt to conform to a certain specification. As far as I know I have only 2 options, neither of which are ideal:
Manually make the same edits on both files and submit both changes in a single changelist. The problem with this, is that I would like P4 history to know that these files are still 100% integrated, but the history will show that they were edited independently.
Only make edits to branch1/file.txt, submit just this file as well as ImportantFile.txt in one changelist, then immediately integrate the change to branch2/file.txt in a 2nd changelist. Now the problem is that I've broken the build for a minute or two until branch2/file.txt gets the required changes.
How can I edit a file, and directly integrate those edits to another file before I submit those edits to the first file?
First off: you may already know this (and have had to make peace with it for reasons beyond your control) but:
ImportantFile.txt should not be outside of your branching structure. If your versioned files depend on it, it needs to be versioned itself, and that means it needs to exist independently in each branch, because branches are a part of your versioning scheme. Alternatively, maybe file.txt should not be branched, if it's required that it be identical in all branches at all times -- why branch something that's not allowed to diverge? But I suspect that just branching everything is the better solution.
Now for the workaround. (If you can't fix the root cause as described above, you've probably got a lot of this sort of thing in your future.)
p4 copy //depot/work/ImportantFile.txt //depot/work/NotABranch/ImportantFile.txt
p4 copy //depot/work/branch1/file.txt //depot/work/NotABranch/file.txt
p4 submit -d "Not a branch! (wink)"
Make your edits in //depot/work/NotABranch and submit them. Nothing is broken because, as stated, this is not a branch, and so it's exempt from whatever policy it is that forces all branches to move in lockstep. Now you can do:
p4 integ //depot/work/NotABranch/ImportantFile.txt //depot/work/ImportantFile.txt
p4 integ //depot/work/NotABranch/file.txt //depot/work/branch1/file.txt
p4 integ //depot/work/NotABranch/file.txt //depot/work/branch2/file.txt
p4 resolve
p4 submit
The merge history shows that both branches of file.txt were pure merges from a single common source, and so future integrations between the two should recognize that they don't need to be re-merged.

Is there a simple way to make perforce 'automatically' ensure that two files, under different paths, always contain the same contents?

We currently have a header file that sits in two different depots (identical copies), and whenever we update it, we have to manually make sure that the other copy is updated as well.
Is there a simple way to get perforce to enforce this? Or would I need to set up something with triggers? (I'm a bit worried about doing it 'properly' if so, don't have any experience with that).
I assume you'd need admin access to the perforce server to do this?
To do this with a trigger, you'd want to put a change-commit trigger on the file:
Triggers:
copy-always change-commit //depot/my/file.h "my-copy-script"
and then my-copy-script would run commands like:
p4 copy //depot/my/file.h //depot/my/other/file.h
p4 submit -d "copy my file to my other file"
But! Keeping two identical copies is an antipattern and you shouldn't do it. Keep one file and use client mappings, branch mappings, streams, or symlinks to make it look like it's in two places. The exact solution you use depends on why you think you need two copies of this file in the first place. :)

What is this Perforce action?

I'm wondering what actions results in the left part of the graph, i.e. the red dashed arrow? This was done by Unreal Engine's Perforce plugin, when I renamed this file and submitted this change. The action shows add if I highlight that revision, but according to legend, this is a merge w/ edit action, so it doesn't seem to match.
The right part is my test, using P4V's move/rename action, and the action shows move/rename, which matches the legend Add (branch w/ edit), so this one seems fine.
So, what exactly happened in the left part? Is it really a merge w/ edit? Is it a correct result if someone is doing rename? Is move/add the only correct result when doing rename?
Thanks.
It's a mind-twister but there isn't necessarily a mismatch.
First the actions: the first is an add because the new file is created in addition to the old one. In contrast, the second is a move/add because you're adding a file by moving it from the old location, hence the old one ceases to exist. Indeed, you start the whole exercise with one file, and end it with two (rather than with three, as you would if you performed two adds; or rather than with one, as you would if you perform two move/adds).
Now the arrows. You're right the naming seems completely out of touch with the naming of the actions. I have no idea why there's the inconsistency.
You're asking about the Merge w/ Edit specifically. Perforce has four similar but distinct actions that could have been used here: p4 integrate, p4 merge, p4 copy, and p4 populate. There are subtle differences that don't matter here. At any case, all these actions do "merge" the file so I think the naming is OK. Intuitively, I feel this could/should have been done by p4 copy (since the target didn't exist, so you didn't have to merge anything) but it's also perfectly possible that Unreal Engine decided to use p4 merge or p4 integrate anyway. That, I believe, explains why the arrow is a Merge. As for the w/ Edit, did you perhaps make a (textual) edit in the file while duplicating it?

perforce unshelving in other branch with partial mapping

Let's say I've shelved files A,B,C
I now want to unshelf this into a different branch, but my spec only has files A,B
Is there any way to do this so that perforce will unshelf the files that are mapped and ignore the rest? Right now I get an error which prevents me from doing any unshelving.
The use case here is I have one branch where I compile a third party lib, and I'd like to move over just the binaries and the public header changes. This changelist is huge so I'd rather not have to manually shelf only what is mapped.
To my knowledge I don't think you can use shelving to move changes from one branch to another. That would be a Merge/Copy depending on the situation.
Using shelving to do that would be a bypass of the (not saying malicious or intentional) versioning process.

Resources