How to get source branch from a pending cherrypick CL? - perforce

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.

Related

git p4 branches not exported

I'm trying to migrate some p4 depots to github using git-p4.py script but I have trouble in exporting branches.
p4 structure is like this:
//depot1/first_directory/second_directory/projects_directory [eg: project_AA] (multiple directories that I want to migrate to separate github repositories)
//depot1/versions_directory/project_AA-or-BB-or-CC_xx_yy [eg: project_AA_01_01) (other directories that contains different release versions of project_directories that should go in github repo project_aa, project_bb etc
P4 branches exist like AA-version_branch and have one or multiple mapping views.
I managed to get tags, commit history (without commits from //depot1/versions_directory/project_AA-or-BB- etc) and content.
The main issue that branches are detected when 'git p4 sync --detect-branches --verbose' is executed, but there are no branch resulted to be added in github.
I executed 'git p4 clone --detect-branches --verbose //depot1#all' just to check what branches will be exported at the depot level, but the result was far away from the expectation like:
remotes/p4/depot1/first_directory/second_directory/project_AA/directory_inside_project_AA
or remotes/p4/depot1/other_directory/tags/a_tag_or_label/project_BB/directory_inside_project_BB
But all resulted branches are not in p4 branch list
I tried the method described on #37607393 but without any result. I believe this is due to perforce repository structure.
Any info or idea that I should try further?

branching when ther has been a a branch with the same name that doesn't exist anymore p4python

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}")

How to identify/verify full integration points in the perforce history

In an analysis of the history in our perforce depot, I need to identify those changes where a full integration from another branch was performed and also find out the exact change number of the source of that integration. Unfortunately, even though such a full integration is a common operation, I could not find any easy and reliable way to detect it in the history. Please let me know if I missed something.
In any case: via a set of scripts using 'p4 filelog' and matching up revision numbers, I managed to find all candidate changes and their respective integration source change. What I am missing is a means to distinguish full integrations from cherry-picks or partial integrations limited to a subdirectory. For this, the closest I could find is the 'p4 interchanges' command, which does exactly the thing I need, except for the problem that the 'toFile' argument cannot have an '#' revision specification.
I would have hoped that
p4 interchanges //depot/sourcebranch#123400 //depot/targetbranch#123499
would tell me whether any changes were missing in the integration point I found, but it only gives the error 'A revision specification (# or #) cannot be used here.' - which matches the documentation.
Is there any other means to examine integration points in the p4 history to distinguish cherry-picks from full merges?
Use the undoc p4 integ -C changelist command:
p4 integrate -1 -2 -C changelist# -Rlou -Znnn
... The -C
changelist# flag considers only integration history from changelists
at or below the given number, allowing you to ignore credit from
subsequent integrations. ...
Hence:
p4 integ -n -C 123499 //depot/sourcebranch/...#123400 //depot/targetbranch/...
should tell you whether sourcebranch#123400 was fully integrated into targetbranch#123499. If you use -C 123498 in theory the difference in the output will show you which files were integrated.
There are probably some edge cases around deleted files -- e.g. if you integrate a deleted file into a file that's deleted at the head revision, it will report "up to date" regardless of integration history, so I can imagine that a file that was skipped for that reason but then subsequently re-added might give a false positive with the above method. (Or it might not -- I have vague memories of possibly fixing that scenario, but undoc bug fixes don't show up in the relnotes...)
Here's an example where foo#2 was integrated into bar#3:
sams-mbp:test samwise$ p4 filelog ...
//stream/main/test/bar
... #2 change 4 delete on 2019/07/21 by samwise#samwise-dvcs-1517552832 (text) 'delete'
... #1 change 3 branch on 2019/07/21 by samwise#samwise-dvcs-1517552832 (text) 'branch'
... ... branch from //stream/main/test/foo#1
//stream/main/test/foo
... #2 change 6 edit on 2019/07/21 by samwise#samwise-dvcs-1517552832 (text) 'edit'
... #1 change 2 add on 2019/07/21 by samwise#samwise-dvcs-1517552832 (text) 'add'
... ... branch into //stream/main/test/bar#1
sams-mbp:test samwise$ p4 integ -n -C 2 foo#2 bar
//stream/main/test/bar#2 - branch/sync from //stream/main/test/foo#1
sams-mbp:test samwise$ p4 integ -n -C 3 foo#2 bar
foo#2 - all revision(s) already integrated.
With -C 2 (before the branch), we see a replay of the integration as it would have happened as of that point in time. With -C 3 (the changelist of the branch), we see "all revisions integrated" because by that point in time it had already happened.
After continuing to try out all combinations of arguments, I finally found a solution that works for me:
p4 interchanges -b SOURCE_to_TARGET //depot/targetbranch/...#targetchange
will print out all changes on the source branch that are missing on targetbranch#targetchange. It will return only changes older than targetchange. If this list contains no changes older than sourcechange, the targetchange was a full integration.
The command may take considerable time to complete when the returned list is long. Unfortunately, I can't find a way to truncate this search, but I can live with that.
As it seems, some of this functionality was buggy up to server version 2018.2 which might have caused difficulties in my earlier attempts.

Perforce can't resolve moved files

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.

How to get the branch/merge source & target from changelist in perforce?

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.

Resources