Git is a distributed (and soon decentralised) versioning or change tracking system, mostly used for managing software source code.
It was created 11 years ago with decentralised development in mind. Every copy of a repository contains the entire history of changes. Development can be done entirely offline and without the need to wait for slow servers. Occasionally these offline repositories need to be synchronised if working together with others. This was a giant step after centralised solutions such as CVS and Subversion.
Imagine a world where you had to wait up to 10–30 seconds to compare or to make changes. That was Subversion in the era of 1 Mbps broadband. With Git it happens in a fraction of a second.
This sounds pretty decentralised, doesn’t it? It is, save one small issue — copying and synchronising repositories.
Git is flexible in this matter. It has a concept called remotes, which are remote endpoints for synchronisation and they can use a variety of protocols. The two most widely used ones are Git over SSH and Git over HTTP — both are centralised.
Initially users had to install their own server software, many times augmented with a web viewer called gitweb. An obvious evolutionary step was the appearance of services like Github, Gitorious/Gitlab, Bitbucket, etc.
While these provide a wonderful service, they have the risk of single point of failure and censorship. Remember the denial of service attack against Github which rendered it unavailable for days? Remember that repositories can be removed based on copyright claims — which might be invalid and reported by malicious actors, yet the onus to prove they are not infringing is on the creator of the repository? And that governments can censor GitHub content?
Git was ahead of its time. In the last 5 years decentralised storage and consensus systems (blockchains) have gained significant footing and we are able to accomplish the decentralisation goal of Git entirely. There is no need for central providers. There is no single point of failure.
All Git objects (metadata and data) are stored on IPFS — a content addressable storage network, while an Ethereum smart contract provides means for access control and stores the pointers to the latest repository revisions.
Mango defines a simple Repository Interface similar to the Token Interface in Ethereum. This allows anyone to write a contract with custom access control or other features.
It should be possible to further extend this and implement other collaboration features, such as issue tracking and pull requests, to provide an entirely decentralised replacement for Github.
Mango isn’t the first to foray into decentralising Git.
Last year GitTorrent introduced a similar system where Git objects are retrieved via the BitTorrent protocol and references are stored in Bitcoin transactions. As a downside it requires server nodes which create the torrents for the requested data.
Earlier this year Git over SSB implemented a system much closer to what Mango is. There is no need for a specific server. Secure Scuttlebutt (SSB) is a cryptographically secured append-only message stream — think about it as a social network feed. It works well with peers you trust, but as far as I understand, there is no consensus code included, therefore you cannot use it between untrusted parties.
How can I try Mango out?
It is very simple. You’ll need to have an environment with node.js/npm and install the following packages:
$ npm install -g mango-admin git-remote-mango
Make sure you also have a local Ethereum node with RPC enabled. For testing purposes I suggest to use testrpc. An IPFS daemon is also needed if replication is desired, but it is not needed for local testing with testrpc.
Once the prerequisites are met a Mango repository can be created:
$ mango-admin create
Creating new repository with administrator 0xaf8843081fd0dc1c4b12053d0ec123a10b91de0e
Sent transaction: 0xe95567ee6fdee21e02061ef6e33f2659943509ca5af5d953dc987ad118ed57fc
Repository created: 0x8add9d064bbd29f3118f11ee46abe0ad9e45aa59
And your local Git repository can be pushed to it:
$ git remote add mango mango://0x8add9d064bbd29f3118f11ee46abe0ad9e45aa59$ git push mango master
Counting objects: 17, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (17/17), done.
Writing objects: 100% (17/17), 5.21 KiB | 0 bytes/s, done.
Total 17 (delta 7), reused 0 (delta 0)
* [new branch] master -> master
And finally, you can clone an existing repository:
$ git clone mango://0x8add9d064bbd29f3118f11ee46abe0ad9e45aa59
Cloning into '0x8add9d064bbd29f3118f11ee46abe0ad9e45aa59'...
Receiving objects: 100% (17/17), 10.59 KiB | 0 bytes/s, done.
Checking connectivity... done.
Voilà, you’re ready!
Mango is in very early stages of development and the protocol is subject to change. If you are interested in how it works or would like to engage in development, then check out the protocol description here. Any comments, suggestions and testing is welcome. You can find me on Twitter, Github and Gitter (Ethereum channels).
Let’s create an entirely decentralised software collaboration tool!
Thanks to Martin Becze for the initial discussion and encouragement.