5 ms·
I'll try to contextualize it in the case of something like AST merging so it's more familiar. Imagine you have file A and file B. In one change someone adds so
by jsunderland323 3y ago
I'll try to contextualize it in the case of something like AST merging so it's more familiar.
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.
- IshKebab 3y agoBut can't you have a custom merge driver for 3 way merges too? So that when you try to merge the changes it does complain? 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.
- jsunderland323 3y ago> But can't you have a custom merge driver for 3 way merges too? So that when you try to merge the changes it does complain? You kind of could, at least for diffing. This is what difftastic does https://difftastic.wilfred.me.uk/ 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/main/floro_infra/meta.floro.json 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.
- jFriedensreich 3y agoi dont see how that solves the issue you describe. 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. 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. 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?
- jFriedensreich 3y agoanother 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. 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. this is the problem most conflict "free" replicated datatypes have, most inherently lose data in at least these situations unless they keep conflict markers for all these situations around until an application solves them at some point in the future.
- jsunderland323 3y agoHN isn't letting me nest further. I'll do my best to answer these in the order I saw them posted. 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 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/backend/src/controllers/UpdateTextWebhookController.ts#L30 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.