You can sort of do these operations with couchdb, but you've got to fight against some bad assumptions for this use case of offline edits that could span weeks or months. From https://wiki.apache.org/couchdb/Replication_and_conflicts:
With CouchDB, you can sometimes get hold of old revisions of a document.
For example, if you fetch /db/bob?rev=v2b&revs_info=true you'll get a list
of the previous revision ids which ended up with revision v2b. Doing the
same for v2a you can find their common ancestor revision. However if the
database has been compacted, the content of that document revision will
have been lost. revs_info will still show that v1 was an ancestor, but
report it as "missing".
That is a very dangerous feature for us. Also, the conflict avoidance algorithm means that users can't work on branches in parallel like in git because couchdb obstructs that workflow with 409 responses. This is a very bad feature when you're collecting data in remote areas and replicating with other databases and don't have the time, battery life, or the expert skills to resolve a "conflict". A database should never have states where it rejects new information.
Note that, as stated, the content of the historical revisions may be missing, but the full lineage will still be there and will be replicated. Actually what happens is that the "_id" field and the "_rev" field (the revision number) will always be present, while the other fields may be removed.
You are also never blocked by a 409. A 409 happens when CouchDB wants to help you reduce the chance that a conflict happens, but you can bypass it and do create a conflict if you don't want to be bothered. In fact, that's how replication works and the only way conoflict do happen: when two dbs replicate to each other, they may have a different history for the same document, but the two histories are sent to the other side so that each side can have all the timelines. You have to use another, non-obvious endpoint for that, see http://docs.couchdb.org/en/1.6.1/replication/conflicts.html?...:
So this gives you a way to introduce conflicts within a single
database instance. If you choose to do this instead of PUT, it means
you don’t have to write any code for the possibility of
getting a 409 response, because you will never get one. Rather,
you have to deal with conflicts appearing later in the database,
which is what you’d have to do in a multi-master application anyway.