I discovered that some old branch integrations in Perforce re-created some files that were previously deleted. Because this was not caught in time, later integrations also modified the branched file.
For example:
MAIN BRANCH
cl 1: X rev#1 == X rev#1
cl 2: X removed in branch
cl 3: X rev#2
cl 4: main -> branch integration, X#2 reappears
cl 5: X rev#3
cl 6: main -> branch integration, X rev#3
What is the "Perforce" way to back out these changes. Clearly, I could go in and delete file X in BRANCH and submit that. However, if it were 100s of files, this would be quite a task.
The more correct path, would seem to be to back out the integration of the file. However, I attempted this, and Perforce does not actually mark the file to be deleted.
Its not clear if you should backout change list 6, or change list 4?
Is this a perforce or user bug? Maybe there is some flag to force perforce to remove files during a "back out" operation.
I'd back out changelist #4. There's no fully automated way to fix this. You could probably write a script that takes care of most of the grunt work. In the future you should use a branch spec to tell Perforce to ignore file 'X' in all future merges.
Related
While testing my application using p4python I came across an intressting issue. I branch a while ago from a main stream directory to a testing directory, I did a revert on that branching since something was wrong with it so the testing branch disappeared (revert and submit). after fixing the issue, I decided to branch again with the same name but P4python said Can't populate target path when files already exist. That branch isn't there any more I don't understand why p4python would output such error. This is the code I use for branching:
result = p4.run("populate", path +"#"+ changelist, destination)
so my question is how to be able to branch again with the same name if the old branch wth that name is deleted?
The populate command only works for the specific case where you're creating a brand new branch; it doesn't handle any cases where you might potentially need to resolve the source against the target, so it will automatically fail if there are any files (even deleted ones) in the target.
If the branch was just for testing, you could obliterate it:
p4 obliterate -y destination/...
Or you could change your code to account for existing files:
p4.run("integrate", f"{path}#{changelist}", destination)
p4.run("resolve", "-as")
result = p4.run("submit", "-d",
f"integrated from {path}#{changelist} to {destination}")
I am trying to integrate a branch with several files that were moved. They were not modified in target branch, yet appear as conflicts. When clicking "accept source" file silently disappears from conflicts dialog, but still remains marked as conflict in the changelist. One way I can fix this is adding -Di flag, but it's a big no-no on my team. I also tried p4 resolve through command line, with same outcome (no error or anything, but nothing is resolved).
What is going on and how can I resolve preserving the move history?
Do:
p4 resolve -as
from the command line. In the vast majority of cases that's all you need to do; it tells resolve to accept the change relative to the base (which means accepting the source in the case where the target hasn't changed).
(updating to include additional info from comment)
If after you do that you get an error like:
can't move (open for delete); must accept other resolve(s) or ignore
it means that the file was moved in the source (which means that normally a resolve -as would move the workspace file to match it), but the file in your workspace can't be moved because it's already open for delete (you can't move a deleted file). This is a pretty rare situation that happens if you move a file, delete it, and then try to resolve those two operations independently (but without submitting in between). In that case you probably want to specifically "ignore" the move resolve (like the error message suggests) by doing:
p4 resolve -ay
If you've somehow gotten your working file into a bad state (maybe you were running random commands before setting up the integrate and the workspace wasn't in a clean state) and either can't figure out how you got here or have no interest in doing forensics when you just want to do a basic integrate and forget about whatever you were in the process of doing before, you can always start over like this:
p4 revert FILE
p4 integrate -b BRANCH FILE
p4 resolve -as
If you have a file that was moved and then deleted in the source, it's not possible for both of those actions to be represented in a single changelist in the target, so the default is to ignore the move and accept the delete (on the theory that since the file is deleted anyway, it doesn't particularly matter where it's deleted):
C:\Perforce\test\movedel>p4 integ A/... B/...
//stream/main/movedel/B/foo#1 - integrate from //stream/main/movedel/A/bar#1,#2 (remapped from //stream/main/movedel/B/bar)
C:\Perforce\test\movedel>p4 resolve -as
c:\Perforce\test\movedel\B\foo - resolving move to //stream/main/movedel/B/bar
//Samwise-dvcs-1509687817/movedel/B/foo - ignored //stream/main/movedel/B/bar
c:\Perforce\test\movedel\B\foo - resolving delete from //stream/main/movedel/A/bar#1,#2
//Samwise-dvcs-1509687817/movedel/B/foo - delete from //stream/main/movedel/A/bar
Note that after resolving move we see an ignored and after resolving delete we see delete. Note also that the history of B/foo is linked to A/bar, which contains the history of the move, so the history isn't "lost", it's just not duplicated.
If you do want to duplicate the move history from the source into the target (so that the target, viewed independently of the source, shows the file as having been moved and then deleted), you need to do the integration in multiple submits:
C:\Perforce\test\movedel>p4 revert ...
//stream/main/movedel/B/foo#1 - was delete, reverted
C:\Perforce\test\movedel>p4 changes A/...
Change 316 on 2022/12/08 by Samwise#Samwise-dvcs-1509687817 'delete bar'
Change 315 on 2022/12/08 by Samwise#Samwise-dvcs-1509687817 'move foo to bar'
Change 313 on 2022/12/08 by Samwise#Samwise-dvcs-1509687817 'add foo'
C:\Perforce\test\movedel>p4 integ A/...#315 B/...
//stream/main/movedel/B/foo#1 - integrate from //stream/main/movedel/A/bar#1 (remapped from //stream/main/movedel/B/bar)
C:\Perforce\test\movedel>p4 resolve -as
c:\Perforce\test\movedel\B\foo - merging //stream/main/movedel/A/bar#1
Diff chunks: 0 yours + 0 theirs + 0 both + 0 conflicting
//Samwise-dvcs-1509687817/movedel/B/foo - copy from //stream/main/movedel/A/bar
c:\Perforce\test\movedel\B\foo - resolving move to //stream/main/movedel/B/bar
//stream/main/movedel/B/bar - moved from //stream/main/movedel/B/foo
C:\Perforce\test\movedel>p4 submit -d "integrate #315"
Submitting change 317.
Locking 2 files ...
move/add //stream/main/movedel/B/bar#1
move/delete //stream/main/movedel/B/foo#2
Change 317 submitted.
C:\Perforce\test\movedel>p4 integ A/... B/...
//stream/main/movedel/B/bar#1 - delete from //stream/main/movedel/A/bar#2
C:\Perforce\test\movedel>p4 submit -d "integrate #head"
Submitting change 318.
Locking 1 files ...
delete //stream/main/movedel/B/bar#2
Change 318 submitted.
What is going on
Perforce is not able to deal with moved files in merge/integrate properly. I can confirm that this is still an issue in the most recent version. We have this case regularly.
Say, team A is working on //OurDepot/ExclusiveContentOfTeamA/ and you are then merging that to team B's branch. Consider the case where team B has not touched (or even looked at) that location.
Merging should be a breeze in this scenario, right? Wrong!
If team A moved and deleted files, it is always a dice roll whether the merge will work or not. Most of the time "accept source" will resolve the issues, but sometimes you get the state you described in your question.
and how can I resolve preserving the move history?
You can't. All you can do is some hacky solution forcing perforce to delete the files (p4 resolve -ay), and then manually repair the state in the branch by re-adding the files as new files. History will be lost.
I am trying to find a source branch of a CL being cherrypicked.
I have the following scenario:
One CL containd same changes to 3 branches: A, B, C. Someone cherrypicked it to branch D.
Obviously when they were doing the cherrypick process, they had to put in a source branch and a target branch, possibly as a branch mapping.
However, when another user is given the pending CL number, how can they work out which of the branches A, B or C was used for cherrypicking?
Where is the information about branch mapping stored? Is there any command in p4 to obtain it?
I need this information before the pending CL is submitted.
I have checked Perforce documentations, but I haven't found anything helpful.
P4 describe command shows only target branch.
Use p4 resolved and/or p4 resolve -n to view the source of a pending integration.
If you're on another client, do p4 -H otherHost -c otherClient resolved to see resolved integrations for the owning client.
If the change is shelved, you can unshelve it (p4 unshelve -s CHANGE) and then run p4 resolved in your own client.
Note that this does not in itself tell you exactly what branch mapping was used (just the individual files), but in practice it's not usually hard to infer the branch mapping based on the paths of the individual files.
Using the API of perforce, I'm going over the history of all the changelists and I need to output a log with all the actions taken in perforce.
For Branching and Merging I want to log the source and target of the action but I can't seem to find it. Not in the changelist class nor in the FileMetaData class.
Perforce keeps the data in the history for every file that was effected by the change but I want to get the general action that was performed. e.g. Branch from //Main/Sample to //Main/Sample-Branch OR Merge from //Main/X to //Main/Releases/A.
Anywhere I can find this data?
What you're looking for is the FileIntegrationRecord(s) for the file revisions in the changelist as returned by Repository.GetSubmittedIntegrations, or possibly the RevisionIntegrationSummary returned by Repository.GetFileHistory.
I am not sure which API you are using, but you will want to use the equivalent of the 'p4 filelog' command.
Example output:
//depot/release/prototype1/docs/Test Plan Template_Baseline.doc
... #1 change 471 branch on 2011/11/15 by jenbottom#resource_portle_dev (binary) 'Integrating to the prototype1 b'
... ... branch from //depot/dev/docs/Test Plan Template_Baseline.doc#1
//depot/release/prototype1/docs/associations
... #1 change 471 branch on 2011/11/15 by jenbottom#resource_portle_dev (text) 'Integrating to the prototype1 b'
... ... branch from //depot/dev/docs/associations#1
Taking a look at changelist 471, we can see what the actions on the files were, but not where they were branched from or to:
Change 471 by jenbottom#resource_portle_dev on 2011/11/15 22:04:33
Integrating to the prototype1 branch in rel dir.
Affected files ...
... //depot/release/prototype1/docs/Test Plan Template_Baseline.doc#1 branch
... //depot/release/prototype1/docs/associations#1 branch
... //depot/release/prototype1/docs/changelog#1 branch
Hope this helps,
Jen.
I am using following command to sync B vob files from A vob
clearfsimport -master -follow -nsetevent -comment $2 /vobs/A/xxx/*.h /vobs/B/xxx/
It works fine. But it will check in all the changes automatically. Is there a way to do the same task but leave the update files in a check out status?
I want to update the file for B from A. Build my programme, and then re-cover the branch. So if the updated files is an check out status, I can do unco later. Well with my command before, everything is checked in. I cann't re-cover my branch then.
Thanks.
As VonC said, it's impossible to prevent "clearfsimport" to do the check in. And he suggested to use a label to recover back.
For me, the branch where I did "clearfsimport" is branched from a label.Let's call it LABEL_01. So I guess I can use that label for recovery. Is there an easy way (one command) to recover the files under /vobs/B/xxx/ to label LABEL_01 ? I want to do it in my bash script, so the less/easy the command is, the better.
Thanks.
After having a look at the man page for clearfsimport, no, it isn't possible to prevent the checkins.
I would set a label before the clearfsimport, and modify the config spec for the new version to be created in a branch (similar to this config spec).
That way, "re-cover" the initial branch would be easy: none of the new version would have been created in it.