Imagine you have file A and file B. In one change someone adds some code that imports something from file B into file A. In another change someone deletes file B without touching file A. That will result in a valid three-way merge. However, your compiler will complain and you will have to update file A to remove the references to file B. This is okay because you can edit the plain-text and fix the inconsistency. This doesn't work for things where you can't really hop in and manually fix the conflict.
You could definitely create a tool that understand the AST and knows how to remove stale references. If you add in the requirement that there cannot be inconsistent states at any commit you've essentially derived an entirely new merging system. Could you build this on top of git? Sure, it's a plain-text system, you could build anything on top it. Is there any gain if the point of the system is to disallow manual conflict resolution and enforce consistent state? I don't think so but maybe I'm not seeing something.
The advantage of building this on top of Git is fairly obvious: you get to use all the existing Git tooling, and you can use Git for other files in the repo that don't need special merge drivers.
You kind of could, at least for diffing. This is what difftastic does https://difftastic.wilfred.me.uk/. Merging is really ambiguous in what the intended behavior of a removed reference is in AST. Do you delete or nullify or something else? How does that affect other upstream references? I'm not sure you'll ever find a satisfying answer there but floro is constrained to static assets, which are a bit more predictable.
> The advantage of building this on top of Git is fairly obvious: you get to use all the existing Git tooling, and you can use Git for other files in the repo that don't need special merge drivers.
So I think there is some confusion here in how this interfaces with code and I'm sorry I didn't think to explain this first. With floro you have a file in your git repository that points to a sha from floro to generate your assets from.
Here's an example https://github.com/florophore/floro-react-native-demo/blob/m...
I think of it sort of like having a package.json and a lockfile. You don't check your dependencies into git because odds are you don't want to deal with merge conflicts in third party dependencies, just the package.json and lockfile. Similarly you wouldn't want to deal with the conflicts of floro in a git repo. So you do still you get to use all the existing Git tooling with respect to your codebase.
The problem really is that git would allow for inconsistent states, which is fine for programmers but tough for anyone who doesn't know how to resolve the inconsistencies.
1) "i dont see how that solves the issue you describe..."
>the only consistency floro can enforce is if i use a color from a color set in an icon in floro and remove the color, it could complain i have to first change the color in the icon.
So it does do this actually, which is super helpful. You can also check for this in CI and choose to fail a build because of the inconsistency. It's also part of the REST api too so you can decide if you want to make a live update to something via webhook based on if inconsistencies are present. (see https://floro.io/docs/dev/api Invalidity Map Endpoint).
> if i delete an icon from the floro repo and my code in git imports this icon and renders it. floro cannot do anything to help there.
Actually, you kind of can. You have to do some static analysis that gets checked into git but you can use this to determine what is safe and unsafe to update in prod. I could delete the tagline of the webiste and modify some other piece of copy and it would not delete the tagline but would modify the other copy in production. This is really up to the codebase in how they want to handle live updates.
Here is an example of the webhook I do this in https://github.com/florophore/floro-mono/blob/main/packages/....
But I do not do this for icons because I don't really want to live update icons in production.
> but this sound like a really minor inconvencience vs not being able to do everything with git. or is there a concrete example where this would matter?
So the above point is where this really matters a lot and is not about minor convenience. Being able to make live updates to a site without having to worry about breaking the production app and going through a buid-pipeline is by far my favorite feature of the whole thing. Could you do this with a headless CMS? Yes/Kind of, it really depends how complicated the asset is and how much you think type-safety really benefits you. There's also a whole host of CI/CD problems you run into then.
> i dont see how that solves the issue you describe.
I don't know if I have much else to add aside from the above comments. If inconsistencies introduced to the repository prevent a translator or designer from using the tool until the inconsistency is resolved that's a really bad experience. I think if you can use plain-text for something, definitely do it. But it's a pretty unpleasant experience for people like translators and non-technical folks.
2) "another point is that enforcing invariancts..."
> another point is that enforcing invariancts is not the task of the repo but of the checks / review system. it is very simple to enforce your described cross file constraint with a ci check and prevent merging.
So yes and no. If we were to analogize this entirely to code I would 100% agree with you, but for simpler structured data types you can definitely describe cascading behaviors that could be anticipated and should be enforced by the version control system, which maybe gets at the heart of why I think it would not be useful to build this on top of git.
> and floro could also not automatically solve the conflict of inconsistency as concurrent deletion and modification of any data is fundamentally undecidable without knowledge of the application logic and business domain and sometimes even human user intent.
It does not use auto-merge, unlike CRDTs it does use user intent if a conflict occurs. It chooses between two sequences of potential acceptable merge results (yours and theirs). I do really describe this in depth in the page I posted above, I'm sorry if it's not clear.
You are correct that you don't get the granularity of picking some changes from yours vs theirs. You have to accept the entire state of either yours or theirs for a conflict before you can make revisions to resolve the conflict but you can manually resolve the consistency issues of the merge conflict in the plugin UIs, I actually show this very briefly at the end of our demo video.
> so your production website loads whatever latest asset version from a floro api endpoint and my repo state is not a snapshot anymore of what what the page will look like on production?
Yes! But it’s your choice to decide which plugins to do this with. You can break your build environment without breaking your production environment, which is really important because you want CI to catch something like a missing icon or a bad invocation of a pluralized string but you also don’t want to block being able to update safe production changes like correcting a minor-typo. Breaking a build because an assets was deleted is easy to resolve for engineers.
> in that case why do the repo connection at all? isnt floro then much more a cms / custom database with versioning for translations/ assets/ colors than an extension of the repo side?
I think it would be very intellectually dishonest to say otherwise (with some minor caveats) but you could say the same about code too. Isn’t github just a CMS for code?
The thing about the snapshot that the code imports at compile time is it allows you to determine the structure of how the application consumes assets in static analysis. This is what allows you to determine what is safe to update live and what isn’t. Could you do this by snapshotting a database and performing static analysis on your imports? Yes, you certainly could but that’s not what CMSs do at all ...and SQL is really not good for merging things. Headless CMSs are built for really redundant data-structures because that’s what marketers need and they nearly all suffer from the same CI/CD issues for that reason. Why do we mostly check i18n string into git and not use CMSs for string content?
Ignoring all the other parts of version control we’re taking for granted here, branching, peer reviews, merging, etc. The big benefit of it all working offline is that you can let the non-engineers, who either lack access control to git or could not technically manage setting up the code base, test out content changes locally on your production site or app. CMSs can do with this with iframes but again, it’s really for blogging content/static content and not i18n. The other area where offline testing shines for people who aren’t engineers is being able to test out content changes on mobile devices over the local-network. That’s not really a thing CMS systems can do at all.