Assumptions about merge sources

- a source represents a branch 
- a branch has had many revisions applied
- revisions we apply to a branch from another branch are always applied UNCHANGED
- in the event of a conflict, we will apply a "pre-changeset" to smooth the application and a "post-changeset" if the applied changeset doesn't match the desired outcome.

on pull
    we end up applying every single source changeset this peer has seen since the last time we saw this peer, one by one
    we possibly apply another two changesets for each changeset to smooth the application



    we skip any source changeset we've seen from another source before
    

on push,
    we publish each changeset we've made targetly.
        - including "after" fixup changesets
        - not including "before" fixup changesets.

assumptions about merge changesets

we can get (and hash): -original database uuid -original database revno -original database author -all changes

Audrey@1:

Createdb
Add ticket 1 - subject 'foo'; status 'new'

Jesse@1:

j pull from a@1

j@1 - foo;new
a@1 - foo;new

j@2  foo->bar
a@2  foo->baz
    
c@1 pull from j@2

    c now has:
        a@1
        j@2


c@2 bar->frotz

c@3 pull from a@2

    a hands c: a@2:foo->baz     

    Conflict

    to target c applies a pre-fixup:  
        frotz->foo
    to target c applies a@2:
        foo->baz
    to target c applies a conflict resolution
        baz->frotz


c@4 push to a@2

    beforehand, a's state: baz
    beforehand, c's state: frotz

    beforehand, c's unpushed transactions: 
        j@2 foo->bar
        c@2 bar->frotz
        c@3
                pre-fixup: frotz->foo
                a@2: foo->baz
                post-fixup: baz->frotz

        so, what do we push?
        options:
            fixup to get a to our earliest state unpushed. that's kind of stupid and results in us replaying everthing all the time.
            compute a single large changeset from a@HEAD to c@HEAD and apply that?


    

investigate "rumor" peer to peer replication

take 2

there's a new peer I've not seen before. I need to merge in all their changes:

    if a changeset comes from a replica@rev lower than our last-seen version for replica, skip it

    for each of their changesets, import it, applying fixups as needed

push

    get the source list of all merge tickets.
    find all target revs which source has never seen.
        - genuine target changesets
        - third-party changesets that the source has no merge ticket for

        - skip "before" fixup changesets 
        - include "after" fixup changesets, since they're merge resolutions


    iterate over these revs the source has never seen.
    when the changeset applies cleanly, just apply it.

    when the changeset does _not_ apply cleanly, 
        - apply a 'before' fix up transaction
        - apply the original changeset
        - apply a merge resolution changeset.
            - TODO: this doesn't feel quite right
            - the resolution should be the same as the equivalent merge resolution transaction on the "pull" variant if it exists.
	                    What info do we have here?
	                        - record uuid
	                        - nearest parent variant
	                        - target variant
	                        - source variant
	                        - information from the 'future (target head)' about the eventual desired outcome 
	                    
    - audit stage:
        compare target head and source head. - they should now be identical, since the last transactions we replayed were all target merge fixup changesets. (is that true?)