Merge multiple branches


We created multiple branches from different Revit models into one stream. How to merge all the branches into one? Thanks!

Hey @chloesun, depends what you’re after:

  • merge things together so you can view them all together: we should support that sooner or later. it’s not yet exposed in the viewer, though it can be done programatically.
  • “manual merge”: receive all the commits you want to merge in one host application, eg. gh, combine them up, and send them.
  • just merge things together in one commit, without caring re merge conflicts (however you’d define a merge conflict in aec): we should be able to allow that to happen, rather easily, but we’d need to know first if it’s actually useful (hence it’s not implemented).

Curious to hear what you think!

1 Like

@dimitrie thanks!

  • merge things together so you can view them all together: we should support that sooner or later. it’s not yet exposed in the viewer, though it can be done programmatically.

I was searching to find ways to do that in the viewer, it would be helpful to have that implemented. For now, how to do it programmatically without using an API gateway like Grasshopper?

Just give my two cents, very premature ideas:
1, Copy from software dev, so eventually, every branch will be merged into main to show the full picture.
The feature I might have in mind is you can choose branches to merge into main, while in the main branch viewer, you can still see the original source (like the Github “blame” feature, something like when you click the original branch name icon, that specific content is highlighted)

Question is when a branch is merged into main, it will no longer be updated right? So you can only merge branches that you are sure that won’t change?

2, More like Photoshop.There is no main branch. Every branch is a living entity, like site, architecutral, structural, MEP…etc. They update constantly and we just need a feature to view them all(turn the layers on /off). While solving “merge conflicts” in this case could be a rough clash detection that you can calculate the intersections among the branches, and highlight the intersections.

For now, I think the second option might be more suitable for AEC workflows

2 Likes

@dimitrie Can you show some examples please?

Hi @chloesun! Sorry for the late reply, we’re “busy” with our retreat (read: eating pizza in various tuscan villages). We’ve decided to do try and solve this as a quick open coding dojo. If you want we can schedule it during a time that you can join as well, if curious. I’ll follow up next week and propose some times!

1 Like

@dimitrie nice retreat, I’m jealous! Let me know your availability, thanks!

1 Like

@dimitrie Any update on this?

Yep, definitively behind on this :sweat_smile: Life & company chores have a way to slice and dice my time. I won’t make any more timing promises until I’m 99% certain I can keep them.

If really urgent and any of you want to have a stab at this, here’s a quick run through off the top of my head:

Assuming you have commit A and commit B, what you need to do is create a new object containing a reference to A and B’s referenced objects, say something like

let commitA, commitB
let mergedObject = { 
  speckle_type: 'Base',
  objects: [ { speckle_type: 'Reference', referencedId: commitA.referencedObject }, { speckle_type: 'Reference', referencedId: commitB.referencedObject } ]
} 

Next up, you need to merge the closure table from A and B’s objects, picking the min depth of each duplicate key (if any), and store it in mergedObject.__closure.

Lastly, mergedObject can be saved via a quick mutation on the gql api (createObject), and you can wrap the returned object’s id in a commit (whilst ideally taking care to populate the parents array with commitA & B’s ids - that’s what it’s for).

@dimitrie oh, not really bother with any promises or not :slight_smile: take you time

On the same topic (or related)… how do you guys think ‘source control’ should take place in Speckle? Is this something for Speckle in the first place? Like, sharing models is one thing, but would it also be supporting stuff like branching, merging, diffing, pull request, etc?

Speckle currently have a notion of a stream. AFAIK, a branch is just another stream, right? Or is it really a branch as in the way git operates? And is the merge you described here, just merging two streams in one? Or does it also tries to resolve conflicts?

Furthermore, I’ve looked a bit into how Revit does ‘versioning’. They have this concept of work sharing, and AFAIK it is only supported locally/network or bim360. When one enables work sharing, Revit gives you features to lock or unlock an element in the model. Basically how source control used to work decades ago :slight_smile:

Curious on what you guys think!

Ha, many questions. Some things still stand from 1.0 time.

Every object in speckle is immutable - if something changes, hashes change, it’s basically a new object. This where the “only forward” mantra of Speckle comes from, and that’s why there’s no need to lock/unlock elements.

More specifically: in 2.0, branches are essentially “labels” for commits, a bit just like in git. Commits are wrappers around a “tree-blob” which contains the actual data (a high level intro is here). Commits can have multiple parents for tracking descendants. Streams are just “repos” right now. If someone used to BIM360 asks, they’re folders :smiley:

Merging: the merge described above is a simple one, without any conflict resolution. Conflict resolution is something hard in AEC, where it’s not just text :confused: It can be:

  • actual 3d clashes - but only some of them, because many can be “ok”
  • element duplication (do you have overlapping representations of the same object from more disciplines?)
  • etc.

In short, it’s in the “eye of the beholder” - that’s why for actual “real” merges the only sound approach is to pull the data into an authoring software of choice (ie, Rhino) and resolve any “conflicts” manually.

Streams are just “repos” right now.

So, a stream can have multiple different files (models) in it?

Merging: the merge described above is a simple one, without any conflict resolution. Conflict resolution is something hard in AEC, where it’s not just text :confused: It can be:

  • actual 3d clashes - but only some of them, because many can be “ok”
  • element duplication (do you have overlapping representations of the same object from more disciplines?)
  • etc.

In short, it’s in the “eye of the beholder” - that’s why for actual “real” merges the only sound approach is to pull the data into an authoring software of choice (ie, Rhino) and resolve any “conflicts” manually.

Interesting!

Thinking out loud… from what I understand (a friend of mine is more of an expert user, so I’m discussing it with him as well), Revit’s primary way of supporting collaboration in the same file is to enable work sharing. For this reason, almost all companies opt to store their models on disk (network), because that is one of the two work sharing options (other one is bim360, which is $$$). The collaboration feature prevents conflicts, so Revit does not have any conflict resolution support.

I was thinking Speckle will enable a new way of saving Revit models. One that is much more transparent and easy to share with other AEC tools and with other teams. But I also have a feeling that it conflicts with how Revit users collaborate, namely via locking elements.

How difficult is it to actually merge in Revit with the current connector? What would the steps be (would like to ask my friend if he can try it out while my developer license for Revit is pending :slight_smile: )?

And how difficult would it be to actually build a diff/merge tool in Revit? I’ve read some papers on diff/merge algoritmes for 3d (and BIM), and I think it would be doable. Speckle could facilitate in the loading of the merging sets. I have a feeling that this would be far more natural (instead of locking), especially given how Speckle works, would you agree?