Isomorphic-git v1.0
isomorphic-git.org
isomorphic-git.org
I'm not talking about making use of some "serverless" backend like Firebase or something. I'm talking about only using git hosting and static website hosting and in browser computation to make "dynamic" websites.
What you do is:
* You make a regular static page with whatever static web page framework or view template software you like that runs in the browser. I got Handlebars to work. (I'm looking at trying Choo next, because it is literally one hundredth of the size)
* Make another "admin" page where the user can input the data. This page first checks out the current git repo.
* When the user hits submit you use the newly edited data to build the static site in the browser and commit/push everything to git where it is automatically pushed to netlify.
You first have to bootstrap this process on your own machine in the first commit.
I've been holding on to this secret for over a year. Well the cats out of the bag now. I haven't run into someone doing something similar with Isomorphic-git yet. I've had it in production for an artist website for almost a year. I don't know if this is good or bad for Gitlabs or Netlifys business model.
Netlify is just the static web page host.
The admin experience leaves a lot to be desired... Slow previews (requires a full build - like a minute!), slow saving, buggy.
Fixing the first two requires a different architecture
On the blog where I have set this up, it goes direct and content editors aren't that happy with the experience
Doing static site generation in the browser would definitely help with previews, at the cost of not working with off-the-shelf static site generators.
I guess here you are adding the "you can edit it from a browser", is that right ?
There are two benefits to my approach, which motivated me to do it.
1. No backend code or database. Not even serverless. All the complexity of managing this is gone. Don't have to worry about quotas or paying for this either as it doesn't exist. We just need a static site host that can pull and host from git. Netlify does this.
2. Perfect caching performance, as we build a new static website when we change any data. Nothing is generated at view time. The thought of each user calling a backend for the same data over and over on each page load, when the page hasn't changed gives me pain. With this all the data is just built directly into the static site and the static site host and the browser takes care of doing http caching if it isn't changed.
A) Git operations on both Github and Gitlab are kind of slow (compared to normal AJAX requests).
B) It requires you to embed Git credentials into your webapp clientside, and I'm more comfortable building secure client sessions than I am messing around with libsodium to encrypt credentials locally.
C) The lack of isolation between my data and site code means that I don't have defense in depth if the credentials get compromised. If someone breaks into my session, they can't only compromise my database, they also have push rights to my entire repository. This is especially problematic for apps where I want multiple people to have access, since I often don't trust them to keep their passwords secure.
D) To expand on that, you can't do any validation of input at all -- clientside validation doesn't count. Your only permission you can grant people is "100% commit access to my entire repo, plus (potentially) the ability to execute arbitrary code during my build process", or "nothing".
E) It's also just honestly a lot more complicated than normal hosting. There ended up being a lot of niggly details that I was fiddling around with that weren't terrible to solve, but left me asking, "what exactly is my end-goal here and is it worth the time I'm putting in?"
The security issues mean that having an open submission form is a pretty bad idea anyway, so really you'd only want to do this for a personal site. Except -- I can't think of any scenario where I want to edit a personal website, I have an Internet connection, and I'm on a computer I'm comfortable typing Git credentials into, but I don't have Git installed. Usually it's just going to be easier to make the edit locally and push to Git the normal way.
----
If you are trying to build a multi-user submission form:
You can build a purely static site on Netlify and use 100 hours of 'serverless' functions for free. Your functions can still do stuff like push changes to Gitlab and trigger Gitlab builds if you don't want to fiddle with a database, except now you can actually run real input validation. Plus, if you're using serverless functions, you can make your submission forms work without Javascript, which is a nice plus.
At the point where you're doing more than 100 hours of work a month running builds, you're also probably at the point where the pure-JS repo solution is going to have a really hard time scaling. And if you do reach the point where 100 hours doesn't cut it, you can scale up Netlify functions without rebuilding your entire submission form to use a different architecture.
----
None of that is to say that the setup Sammi describes isn't worth playing around with, or that you can't build a working site with it, or that people should be discouraged from trying. It's very cool; and it's useful to try things like this even just from the perspective that they're fun projects that will make you a better coder.
I just question whether it's really a holy grail, or even a good idea to hook up to your own Gitlab account. I would posit that the reason you see fewer people actually following through and adopting Isomorphic Git in this way isn't because no one's thought of it, it's because you can build the same solution more efficiently and safely for the same price ($0) using serverless functions or (worse-case) setting up a single $5 Linode VPN that you share between all of your sites.
You don't need to embed the git credentials in the site. I just made a login form that takes the gitlab credentials. Gitlab gives you 5 users per project, so you can give several people access.
You're absolutely right that this is not a replacement for a full blown CMS, or for when server side input validation is necessary, or for when different people need different edit rights. I've stayed away from using the term CMS for this reason as it implies that complex content management abilities are required. These "dynamic static" pages only give you full edit rights or not, and you need to build everything manually as it is a static website after all.
I have found this approach useful for hosting a static website for an artist where I wanted the artist to be able to easily update some info on the site. I imagine there are a lot of cases like this where you are building a small static website for someone else who isn't a developer and you want them to be able to update the site themselves later, so they don't have to bother you about it.
(I have no affiliation with either project, just looking for options to use git in-browser and in node.)
But since we’re here! For those who don’t know the word from outside of the dev sphere, in maths it refers to having 2 way mappings between 2 structures. You can do it between totally seemingly unrelated parts of maths (you just need to show how to map between them). As a result, anything you’ve proved in one space holds true in the other. It can be useful if you have an intuition and understanding of one of the spaces but not the other.
I’m trying to think of a nice example but I haven’t thought about this type of maths for a couple of decades now. Answers on a postcard please!
0. I have two sets of things, and I can perform operations on each set
1. These two things are the same size (this is your example)
2. If I do operation A on elements (a, b) in set A, then perform the isomorphism on the result, this gives me the same thing as if I performed the isomorphism on a and b independently then performed operation B on their result
3. The isomorphism has an inverse with the same properties
[There are various types of isomorphism depending on what part of maths you’re thinking about. But they all have roughly this idea of “same size” and “preserves something cool that I can do in each of the spaces”]
Bijective means that a mapping is exactly one to one.
Homomorphic means that "structure is kept". E.g. in a vector space you can add and multiply by a scalar, so a mapping f is homomorphic if for all x, y in the vector space and lambda a scalar
f(lambda*x + y) = lambda*f(x) + f(y)The classic example is a function which maps an interval to a circle by applying cos and sin to get the coordinates; this is continuous as small changes in the interval result in a small change in the position on the circumference, but its inverse is not continuous because there will be a point on the circle where the nearby points on one side come from the start of the interval but the nearby points on the other side come from the end of the interval.
Why is the definition in one community special?
Isomorphism means "same shape" from Greek, sounds like a good way to describe code written in the same language running in different environments.
I don't really have a 'math background' (engineering graduate, but I don't think that counts, a mathematician certainly wouldn't) but I know (enough, roughly, layman's definition) what it means in mathematics, and work in software engineering.
I have absolutely no idea why this project is called 'isomorphic', it doesn't make any sense to me however much I squint, and doesn't seem to be explained anywhere.
I'd guess it's just an arbitrary name and isn't supposed to have meaning? Though it's a library for `git`, why not just call it `git`? shrugs
Naming things is hard.
Many such systems do work like that, but the UID is chosen by the author, so invariably it's a close match to the import/use-it name, and often it's actually the preferred name because the other had to be mangled to be syntactically correct in a program. Consequently, the main display name is the UID; not the import/use-it name.
The UID should be generated by the package manager, and only the import/use-it name chosen by the author. The latter would be the one prominantly displayed, and be allowed to conflict with other packages (that have different UIDs).
Even if you wanted to use two that shared an import/use-it name, there could just be a way of renaming them in the requirements/lockfile, e.g.:
[dependencies]
d34db33f = { version = "^0.1", name = "isomorphic_git" }
l333333t = { version = "^3.2", name = "native_git" }
where usually both of those use the import/use-it name `git`, and the names `isomorphic_git` & `native_git` are whatever I fancied for this project with this dependencies file - could've been `foo` & `bar`.(Perhaps a more human-friendly format would be `git = "^0.1"`, and we only have to specify something like `= { uid = "d34db33f", ...` when the package manager detects that there is a naming collision. Of course the lockfile, if used, would already have the UID, in case a colliding package was suddenly created.)
https://en.wikipedia.org/wiki/Complex_number#Matrix_represen...
I'm having a failure of imagination on the browser side though - anybody got killer use cases running git in the browser?
Glitch already has this feature although it’s currently a bit buggy. It may even be based on isomorphic git, not sure.
https://github.com/mattdesl/canvas-sketch/blob/master/docs/e...
Client side git would mean one less reliance on nodejs.
I was planning on storing this history in the database as raw JSON, then diffing the JSON server-side, but this may provide a more robust solution.
[1] : https://github.com/benjamine/jsondiffpatch/blob/master/READM...
I think there’s two benefits of isomorphic git for this use case.
1. It’s more api agnostic: if I wanted to support Gitlab, I wouldn’t have to write substantially more code tailored specifically for Gitlab’s API because it speaks git. You would only have to switch out Github's auth for Gitlab's auth. I also found that add multiple files and versioning them with Github’s API is a pain; they’re remaking a client called Octokit but it’s pretty underdeveloped right now.
2. Offline version control: you shouldn’t have to be online to take notes. With isomorphic git I can add and commit, and then push back to GitHub later when I have Internet. Fun fact: to get git to work on the browser, the author of isomorphic-git wrote a library to port NodeFS commands backed by IndexedDb. This means you can also have offline image drag-and-drop.
There are some minor issues with isomorphic-git when I checked a month ago.
- Largest one is only fast-forward merges are supported; not sure how to get around this one besides cloning the remote Github branch and maybe manually merging files.
- Another one is a bug with git init followed by git add remote and git pull which leads to a reference error because no local commit has been made yet; you can imagine a user who immediately logs in with Github so you want to sync with a pre-existing repo.
Isn't something like OT ( operational transforms ), or CDRT ( Commutative Replicated Data Type ) a better way to do this?
I wasn't familiar with OT and CDRT, so maybe I'm off the mark. They seem to try to solve real-time collaboration between multiple users editing same part of same document. This would always require some meta-document or meta-channel where users coordinate what should be changed, in what way and who does what. I would argue that git model is better: user decides when to pull and when to push changes, and the communication between collaborators is outside the scope of the versioning system.
Collaboration is just one application. Even single-user content creation could vastly benefit from built-in versioning. This would eliminate some mental burden and usage friction (tagging), and open up more possibilities to experiment with different directions (branching). The feeling you get when you check-in working version of your code and you are now free to break stuff, that kind of feeling is missing when creating slides, graphics, music, CAD design...
[1] https://github.com/isomorphic-git/isomorphic-git/issues/698
edit: fix link
Sorry, I know this comes off as a bit dickish, but I'm interested to know the circumstances that lead to this point of view :)
The other option could be compiling libgit2 to native code/wasm and use it in RN and web, but it will be harder then just import js-only npm.
Very different from "this app has packaged tutorials and tools just start at lesson 1"
React Native opened the door to allow me to build apps and, realistically, I'm not going to spend the time battling through trying to get native git working through React Native. If there's a native developer out there that wants to tackle this problem and wrap it up in a nice JS module then I'd be in your debt!