Robomerge - Files isolated in perforce stream spec are being automatically merged

This question was created in reference to: [Ignore Path [Content removed]

Hello,

We have modified our stream spec recently to include an ‘isolate’ path to prevent the files located in the path from being propagated to other streams.

share …

import+ Engine/… //unreal/proj1/unreal5/Engine/…

import+ Scripts/… //unreal/build/ScriptsUGS/…

import+ proj1/Raw/… //proj1/raw/main/Content/…

isolate BuildSystem/…

However, Robomerge continues to merge these files between streams. Does Robomerge generally respect these stream spec settings when merging?

Thanks!

Steps to Reproduce

  1. Create 1 mainline StreamA and branch out 1 development StreamB (StreamA is a parent of StreamB).
  2. On StreamA, modify the stream spec and isolate a directory in the Paths.
  3. On StreamA, edit and submit a file located in the isolated directory.
  4. Robomerge merges the file to StreamB.

It depends on how your branchmap is configured.

If it is just a basic stream set up then yes robomerge should respect it in so much as robomerge is just issuing perforce integrate commands using -S which use the stream view for determining which files to merge and perforce should not be merging the isolated files.

If you’ve configured a branchspec for the relationship between the two streams then you will need to add a filter in to the branchspec for that folder as well because isolates in the stream view are unknown by the branch mapping and it will continue to pull the files in.

I will put in a note to try and do a stream depth testing pass across robomerge when I have time (or more likely as a task for someone to learn about robomerge if we ever get someone to back me up!).

Can you confirm that with the rootPath removed and the stream without a trailing slash that the isolates are working as expected now?

We are using the basic stream set up on our side, here is an example of the branchmap.json

{

“defaultStreamDepot”: “proj1”,

“isDefaultBot”: true,

“globalNotify”: ,

“emailOnBlockage”: false,

“branches”: [

{

“name”: “main”,

“rootPath”: “//proj1/dev/main/…”,

“stream”: “//proj1/dev/main”,

“aliases”: [ “main” ],

“flowsTo”: [ “robomerge_test” ],

“forceAll”: true,

“notify”: [ “joneill”]

},

{

“name”: “prodmilestone01”,

“rootPath”: “//proj1/milestone/prod-milestone01/…”,

“stream”: “//proj1/milestone/prod-milestone01”,

“aliases”: [ “prodmilestone01” ],

“flowsTo”: [ “main” ],

“forceAll”: true,

“notify”: [ “joneill”]

},

{

“name”: “robomerge_test”,

“rootPath”: “//proj1/milestone/robomerge_test/…”,

“stream”: “//proj1/milestone/robomerge_test”,

“aliases”: [ “robomerge_test” ],

“forceAll”: true,

“notify”: [ “joneill”]

}

]

}

In our test we are robomerging between //proj1/dev/main/… (parent) and //proj1/milestone/robomerge_test/… (child) and isolating the Buildsystem folder in the parent, //proj1/dev/main/BuildSystem/.

If I try to use perforce merge commands or the merge/integrate UI in p4v I am blocked from merging the isolated folder as expected, but our Robomerge is merging files in the isolated paths. Is it the ‘forceAll’ in our config?

I think it is the use of rootPath that is causing this issue. By specifying a rootPath I believe the robomerge integration commands are done as file path integrations which, like branchspecs, will bypass the StreamView integrations.

I tried removing the rootPath - I’m not sure why we are duplicating this path info along with the “stream” path in our config, but Robomerge continues to integrate isolated files.

integrate -Ob -Or -Rd -Rb -c248 //proj1/dev/main/…[Content removed]246 //proj1/milestone/robomerge_test/…

{

“defaultStreamDepot”: “proj1”,

“isDefaultBot”: true,

“globalNotify”: ,

“emailOnBlockage”: false,

“branches”: [

{

“name”: “main”,

“stream”: “//proj1/dev/main/”,

“aliases”: [ “main” ],

“flowsTo”: [ “robomerge_test” ],

“forceAll”: true,

“notify”: [ “joneill”]

},

{

“name”: “robomerge_test”,

“stream”: “//proj1/milestone/robomerge_test/”,

“aliases”: [ “robomerge_test” ],

“forceAll”: true,

“notify”: [ “joneill”]

}

]

}

-------------------

I also tried putting the rootPath back and removing the “stream” option from the config but robomerge continues to integrate isolated files with the same arguments:

integrate -Ob -Or -Rd -Rb -c268 //proj1/dev/main/…[Content removed]267 //proj1/milestone/robomerge_test/…

This same p4 integrate command launched in cmdline also ignores the streamspec options.

I am surprised that it isn’t causing an error elsewhere but can you try remove the trailing slash on the stream names … if you do p4 stream -o //proj1/dev/main/ you’re going to get an error message like Null directory (//) not allowed in ‘//proj1/dev/main/’. I would have imagined that would cause the branchmap to fail to load and work, but there’s a chance that it is skirting that somehow and having it fall in to a classic branch configuration instead of a stream configuration.

I could try and set up a repro to validate this theory, but I’m guessing you can try it quicker.

I will also note that we don’t currently run robomerge against any depots that have a stream depth > 1. I believe any logic is trying to take that in to account, but there is some possibility there are code paths that are making problematic assumptions based on a stream definition being //<depot>/<stream> always

Ah yeah, when I was first testing with the rootPath removed from the robomerge config, the stream did not have the trailing slash like so:

{

“name”: “main”,

“stream”: “//proj1/dev/main”,

“aliases”: [ “main” ],

“flowsTo”: [ “robomerge_test” ],

“forceAll”: true,

“notify”: [ “joneill”]

},

{

“name”: “robomerge_test”,

“stream”: “//proj1/milestone/robomerge_test”,

“aliases”: [ “robomerge_test” ],

“forceAll”: true,

“notify”: [ “joneill”]

}

This caused the following error, which on a second look is reporting on a path with a stream depth of only 1 when there should be 2..

[Robo Startup:ABU] [error]: failed to parse/validate branch specs file

Stream //proj1/main not found

Stream //proj1/robomerge_test not found

Our production robomerge config is set up like this, with both the rootPath and stream (no trailing slash) and no errors are reported:

{

“name”: “main”,

“rootPath”: “//proj1/dev/main/…”,

“stream”: “//proj1/dev/main”,

“aliases”: [ “main” ],

“flowsTo”: [ “robomerge_test” ],

“forceAll”: true,

“notify”: [ “joneill”]

},

The isolates don’t work with the rootPath removed and the stream without a trailing slash. Instead Robomerge is showing errors:

2025/06/17 20:09:54.653 [Robo Startup:ABU] [error]: failed to parse/validate branch specs file

Stream //proj1/staging not found

Stream //proj1/main not found

Stream //proj1/prodmilestone01 not found

Stream //proj1/robomerge_test not found

Stream //proj1/unreal5 not found

Stream //proj1/unreal5-staging not found

{

“defaultStreamDepot”: “proj1”,

“isDefaultBot”: true,

“globalNotify”: ,

“emailOnBlockage”: false,

“branches”: [

{

“name”: “staging”,

“stream”: “//proj1/staging/main”,

“aliases”: [ “staging” ],

“notify”: [ “joneill”]

},

{

“name”: “main”,

“stream”: “//proj1/dev/main”,

“aliases”: [ “main” ],

“flowsTo”: [ “robomerge_test” ],

“forceAll”: true,

“notify”: [ “joneill”]

},

{

“name”: “prodmilestone01”,

“stream”: “//proj1/milestone/prod-milestone01”,

“aliases”: [ “prodmilestone01” ],

“flowsTo”: [ “main” ],

“forceAll”: true,

“notify”: [ “joneill”]

},

{

“name”: “robomerge_test”,

“stream”: “//proj1/milestone/robomerge_test”,

“aliases”: [ “robomerge_test” ],

“forceAll”: true,

“notify”: [ “joneill”]

},

{

“name”: “unreal5”,

“stream”: “//unreal/proj1/unreal5”,

“aliases”: [ “unreal5” ],

“flowsTo”: [ “unreal5-staging” ],

“forceAll”: true,

“notify”: [ “joneill”]

},

{

“name”: “unreal5-staging”,

“stream”: “//unreal/proj1/unreal5-staging”,

“aliases”: [ “unreal5-staging” ],

“notify”: [ “joneill”]

}

]

}

Did you modify robomerge to add “stream” as a branchmap parameter? We only support streamName for overriding “name” as the name of the stream it is looking for, and that does not want to deal with multi-depth streams at all (i.e. “streamName”: “proj1/unreal5” is an error due to the / in the name), so I can’t really look in to why that is failing parse. It is possible you could improve the validation on “stream” and get it working and if so and you’re having good success with multi-depth streams we could look at a PR to bring that functionality in to our code.

Since you’re working with multi-depth streams and out of the box robomerge is just not ready to handle that, you may find yourself needing to stick with your rootPath mechanism but that will force you to use a branchspec to mirror the isolates and keep them from being merged.

Apologies for the trouble and if we get an opportunity to investigate full multi-depth support we will, but unfortunately since we are not depending on that functionality it is unlikely to be prioritized given the current support posture on robomerge.

Ah yeah, I see. Sorry, this is not code I have worked with but I do see a basic ‘stream’ parameter has been implemented.

/* @custom - BEGIN bug fix

// add the stream to be able to get the stream of the branch

\*/

stream:string

// @custom \- END

streamDepot: string

streamName: string

streamSubpath: string

workspace: (string \| null)

We will put some more thought into this because it is not clear why this was done.

Thank you very much for your guidance with this :slightly_smiling_face: