All this is assuming operation against a custom gotd(8) server which would queue up incoming commits and attempt a 'trivial-rebase' operation for each commit in sequence. Commits which fail 'trivial-rebase' are rejected and reported as 'out-of-date' to the client. 'trivial-rebase' merges trees successfully as long as all file content changes apply to the expected 'base blob' content (which implies a conflict-free file merge according to diff3), all added blobs get added where no blob exists yet, and only existing blobs get deleted. (As an analogy, this part of gotd(8) would operate roughly like some sort of Gerrit server with merge strategy set to 'rebase-if-necessary', but without a code review UI and without Java.) gotd(8) would also regulate read/write access to branches and perform various sanity checks on commits: require a log message, reject merge commits except where necessary (e.g. merges of vendor branches), ... Another responsibility of gotd(8) would be to keep repo mirrors in sync. --- got pull: fetch latest master branch from server to local origin/master origin/master has new commits if fast-forward possible: set master -> origin/master if running in a worktree: { if fast-forward was possible: automatically run 'got update' ('got pull' implies 'got up') else: attempt server-style trivial-rebase of master onto origin/master if success: set work tree's branch to rebased master branch (implied got up -b) else: require manual rebase + resolve conflicts } else: existing worktrees will have to be updated/rebased manually --- got push: attempt push + trivial-rebase on server out-of-date ? -> require 'got pull' --- "push by default" commits allow for "branchless" development (committing local changes against a central server and local repo at the same time) got checkout work work work get OKs for your local changes! got OKs? (optionally: stage OK'd changes with 'got stage') got commit create temp commit object; attempt push + trivial-rebase on server if success: temp commit becomes new head of local master optionally, user may run 'got pull' to rebase local version of master else: (require unstage if changes were staged) require got pull try to commit again (The fossil SCM has already implemented an implied-push-on-commit design.) --- repo/gotconfig syntax ideas: [[[ # remote private mirrors remote "openbsd_src" { repository "src" server got.openbsd.org protocol ssh user stsp } remote "my_src_mirror" { repository "src" server got.stsp.name protocol ssh user stsp } # remote public mirrors remote "public_src_mirror_anonssh" { repository "src" server got.stsp.name protocol ssh user anonymous } remote "public_src_mirror" { repository "src" server got.stsp.name protocol https # no authentication credentials for this remote since https is read-only } # read from local mirror and push to main server # "sync-to" enables push by default with 'got commit' # implied mapping: refs/heads/master <-> refs/remotes/openbsd_src/master branch master pull-from my_src_mirror sync-to openbsd_src # read from local mirror and push to local mirror # "push-to" means commit locally, push manually # implied mapping: refs/heads/my_branch <-> refs/remotes/my_src_mirror/my_branch branch my_branch pull-from my_src_mirror push-to my_src_mirror # same as above, pull from and push to local mirror: branch my_branch remote my_src_mirror # pull from and push to local mirror, use push by default with 'got commit' branch synced_branch sync-with my_src_mirror # read-only access, anoncvs-style branch master pull-from public_src_mirror_anonssh # read-only access over https branch master pull-from public_src_mirror ]]] read-only config for just keeping /usr/src up-to-date with 'got update': [[[ remote "origin" { repository "src" server got.openbsd.mirror.example.com protocol https mirror-references # map refs/* <-> refs/* } # mapping: refs/heads/master <-> refs/heads/master branch "master" pull-from "origin" ]]] --- Known implications of the above design for the implementation: For each changed file, the 'trivial-rebase' operation needs to know the ID of the blob which the new file content is based on ("base-blob ID"). Otherwise the out-of-dateness check in 'trivial-rebase' cannot work. To satisfy this requirement, the client<->server protocol could require file content modifications in a chain of commits being pushed to be expressed in terms of GOT_OBJ_TYPE_REF_DELTA objects against known base blob IDs. The client can read such base blob IDs from the latest commit in its copy of the branch (e.g. refs/remotes/origin/master). For simplicity, it might make sense to require the protocol to express all file modifications in this way (GOT_OBJ_TYPE_REF_DELTA). File additions could be expressed as a delta against the empty blob's hash as a base. File deletions could send a delta which simply deletes all content from the specified base blob in addition to an explicit 'delete' command to allow the server to distinguish this case from an empty file on disk. The above functionality could be implemented via a Git protocol extension.