Git was created as a distributed version control system (VCS), in contrast to the VCS systems that were most widely used at the time, which denote one replica as the canonical upstream master source. Existing project hosting websites soon began supporting git and some new ones sprung up as well; but even the new ones were modeled upon the traditional "hub" paradigm; with a single canonical upstream replica and all other replicas implicitly and permanently relegated as "forks". This type of website well serves the traditional purpose of facilitating collaboration and end-user participation; but not at all, in the decentralized spirit of Git.
Indeed, it is usually the case, even with Git, that one replica will be designated as the canonical upstream; so this retro-fitting of Git upon the tradition hub model is not often contested. Philosophically speaking though, this has the consequence of casting all software projects and development teams as hierarchical in nature; which is often undesirable, as it is antithetical to truly open project "structures" such as adhocracy.
Furthermore, the centralized infrastructure, which in nearly all current public instances, is operated by a commercial third-party and contingent on it's profitability, is a liability to anyone relying on it for their long-term infrastructure. Remember Google Code?
The goal of this project is to support the familiar collaborative features of the centralized web hosts with a decentralized design that, like Git itself, does not rely on a central host and can be self-hosted by anyone; with all such independent peers cooperating to form a larger logical network of inter-operable services. Also, because this system is intended to be operated by anyone, even on modest hardware such as their personal computers, ultra efficiency and security are also high-priority goals. For example, no long-running processes will be allowed; instead, all Git operations will be fully pre-emptable to prevent the "slow loris" bottle-necks; which are a serious limitation and security issue for existing self-hosted solutions such as Gogs, the system that NotABug is currently using.
Background: Given: that fred.org and barney.com are public instances implementing the protocol above And: user 'fred' creates an account on fred.org And: user 'barney' creates an account on barney.com Then: user 'fred' is assigned the repo URL name-space 'fred.org/fred/' And: user 'barney' is assigned the repo URL name-space 'barney.com/barney/' Then: user 'barney' creates a repo 'barney.com/barney/barney-made-this' Scenario: user forks a foreign repo When: fred visits 'barney.com/barney/barney-made-this' And: fred presses the 'fork' button Then: fred is asked to enter (or select) the domain of his home-server When: fred indicates the domain of his home-server as 'fred.org' Then: fred is redirected to 'fred.org/login' which is a pass-through if he is already signed in When: fred is authenticated Then: the 'fred.org' server clones the 'barney-made-this repo' into fred's name-space And: the 'fred.org' server posts a notification addressed to the 'barney.com' server indicating that user 'email@example.com' has forked the repo 'barney/barney-made-this' And: fred is redirected to 'fred.org/fred/barney-made-this' And: the web page at 'fred.org/fred/barney-made-this' indicates it's parent fork with a link to 'barney.com/barney/barney-made-this' And: the web page at 'barney.com/barney/barney-made-this/forks' indicates it's child fork with a link to 'fred.org/fred/barney-made-this' Scenario: user posts a merge request on a foreign repo Given: that fred has forked 'barney.com/barney/barney-made-this' as 'fred.org/fred/barney-made-this' And: fred has pushed new commits to his 'barney-made-this' fork And: fred visits 'fred.org/fred/barney-made-this' When: fred presses the 'merge request' button Then: the 'fred.org' server posts a notification addressed to the 'barney.com' server indicating that user 'firstname.lastname@example.org' has posted a merge request to the repo 'barney/barney-made-this' And: the 'barney.com' server creates a 'PR' type issue (e.g. ID# '42') And: the 'barney.com' server adds the event to an 'unseen-alerts' db array for user 'barney' And: the 'barney.com' server optionally notifies barney per barney's preferences And: fred is redirected to the 'PR' type issue at 'barney.com/barney/barney-made-this/issues/42' Scenario: user posts a comment on a foreign repo issue When: fred visits 'barney.com/barney/barney-made-this/issues/42' And: fred fills the 'comment' text-box and presses the 'send' button Then: fred is asked to enter (or select) the domain of his home-server When: fred indicates the domain of his home-server as 'fred.org' Then: fred is redirected to 'fred.org/login' which is a pass-through if he is already signed in When: fred is authenticated Then: the 'fred.org' server posts a notification addressed to the 'barney.com' server indicating that user 'email@example.com' has posted a comment to the repo issue at 'barney.com/barney/barney-made-this/issues/42' And: the 'barney.com' server creates a new comment (e.g. ID# '2') And: the 'barney.com' server adds the event to an 'unseen-alerts' db array for user 'barney' And: the 'barney.com' server optionally notifies barney per barney's preferences And: fred is redirected to the issue at 'barney.com/barney/barney-made-this/issues/42#comment-2' Scenario: user receives notifications for important events Given: user 'firstname.lastname@example.org' has posted a merge request to the repo 'barney/barney-made-this' Then: the 'unseen-alerts' db array for user 'barney' contains a reference to the 'PR' type issue with ID# '42' as posted by user 'email@example.com' And: barney optionally receives an email notification with a link to 'barney.com/barney/barney-made-this/issues/42' When: barney logs into his home-server 'barney.com' Then: he sees a notification icon which is a link to 'barney.com/barney/barney-made-this/notifications' When: barney visits 'barney.com/barney/barney-made-this/notifications' Then: barney sees a link to the PR issue from user 'firstname.lastname@example.org' 'barney.com/barney/barney-made-this/issues/42'
NOTES / RFCs:
only some potentially confusing cross-server use-cases are addressed here - but not the most obvious straight-forward cases such as "a user views their own fork" and "a user comments on their own fork" - those o/c can be added later if these stories become acceptance tests - feel free to add your own issues/questions/comments on the wiki
all example workflows above are entirely atomic - e.g.
all example workflows above are entirely autonomous - ie: regardless of which user initiates an event or, which client is used, or which project is the source or target - the initiating user's home-server mediates every interaction - all instances have full authority over their own data and zero authority over data on other instances
all example workflows above are entirely symmetrical - ie. every occurrence of 'fred' and 'fred's home-server' could be replaced with 'barney' and 'barney's home-server' with no loss of generality - no server has any more or less capability than or authority over any other
the "user forks a foreign repo" scenario above is a streamlined version of the one originally suggested that had fred press the "login" button on the foreign site - that immediately would be a source of confusion - no one will press the 'login' on a site where they know they have no credentials - it then had fred being redirected to a dummy page on his home-server 'fred.org/remotes/barney.com/barney/barney-made-this' where he could then press the 'fork' button - that seems like a unnecessary redirect to an unnecessary page which represents data that the home-server does not yet have - the user should be able to simply press the 'fork' button on the foreign site and be redirected immediately to the newly created fork on the home-server (guarded by the pass-through login check)
the 'unseen-alerts' db array mentioned in the "user posts a merge request on a foreign repo" scenario is for example presented on the web page 'barney.com/barney/barney-made-this/notifications' and cleared when the user next visits the URL associated with each alert such as in the "user receives notifications for important events" story (issue #18)