mirror of
https://github.com/ilyakooo0/urbit.git
synced 2025-01-02 03:52:13 +03:00
Merge remote-tracking branches 'anton/nobreach' and 'my/clayhammer' into test
Conflicts: urb/urbit.pill
This commit is contained in:
commit
417dda3aaf
@ -100,7 +100,7 @@
|
||||
house :: program state
|
||||
== ::
|
||||
++ he :: per session
|
||||
|_ [[ost=bone moz=(list move)] session] ::
|
||||
|_ [moz=(list move) session] ::
|
||||
++ dp :: dojo parser
|
||||
|%
|
||||
++ dp-default-app %hood
|
||||
@ -670,7 +670,11 @@
|
||||
==
|
||||
::
|
||||
++ he-abet :: resolve
|
||||
[(flop moz) %_(+> hoc (~(put by hoc) ost +<+))]
|
||||
[(flop moz) %_(+> hoc (~(put by hoc) ost.hid +<+))]
|
||||
::
|
||||
++ he-abut :: discard
|
||||
=> he-stop
|
||||
[(flop moz) %_(+> hoc (~(del by hoc) ost.hid))]
|
||||
::
|
||||
++ he-beak -:he-beam
|
||||
++ he-beam :: logical beam
|
||||
@ -681,7 +685,7 @@
|
||||
++ he-card :: emit gift
|
||||
|= cad=card
|
||||
^+ +>
|
||||
%_(+> moz [[ost cad] moz])
|
||||
%_(+> moz [[ost.hid cad] moz])
|
||||
::
|
||||
++ he-send
|
||||
|= [way=wire him=ship dap=term cop=clap]
|
||||
@ -844,10 +848,10 @@
|
||||
==
|
||||
::
|
||||
:: pattern: ++ foo |=(data he-abet:(~(he-foo he (~(got by hoc) ost)) data))
|
||||
++ arm (arm-session (~(got by hoc) ost.hid))
|
||||
++ arm (arm-session ~ (~(got by hoc) ost.hid))
|
||||
++ arm-session
|
||||
|= ses=session
|
||||
=> ~(. he [ost.hid ~] ses)
|
||||
|= [moz=(list move) ses=session]
|
||||
=> ~(. he moz ses)
|
||||
=- [wrap=- +]
|
||||
|* he-arm=_he-type
|
||||
|= _+<.he-arm ^- (quip move ..he)
|
||||
@ -856,9 +860,12 @@
|
||||
++ peer-sole
|
||||
~? !=(src.hid our.hid) [%dojo-peer-stranger ost.hid src.hid]
|
||||
:: ?> =(src.hid our.hid)
|
||||
~? (~(has by hoc) ost.hid) [%dojo-peer-replaced ost.hid]
|
||||
=^ moz .
|
||||
?. (~(has by hoc) ost.hid) [~ .]
|
||||
~& [%dojo-peer-replaced ost.hid]
|
||||
~(he-abut he ~ (~(got by hoc) ost.hid))
|
||||
=+ ses=%*(. *session -.dir [our.hid %home ud/0])
|
||||
(wrap he-peer):(arm-session ses)
|
||||
(wrap he-peer):(arm-session moz ses)
|
||||
::
|
||||
++ poke-sole-action
|
||||
|= act=sole-action ~| poke/act %. act
|
||||
@ -872,7 +879,6 @@
|
||||
++ pull
|
||||
|= [pax=path]
|
||||
^- (quip move +>)
|
||||
=^ moz +>
|
||||
he-abet:~(he-stop he [[ost.hid ~] (~(got by hoc) ost.hid)])
|
||||
=^ moz +> ~(he-abut he ~ (~(got by hoc) ost.hid))
|
||||
[moz +>.$(hoc (~(del by hoc) ost.hid))]
|
||||
--
|
||||
|
@ -56,6 +56,11 @@
|
||||
~? ?=(^ saw) [%kiln-spam-lame u.saw]
|
||||
[~ +>]
|
||||
::
|
||||
++ coup-kiln-reload ::
|
||||
|= [way=wire saw=(unit tang)]
|
||||
~? ?=(^ saw) [%kiln-reload-lame u.saw]
|
||||
[~ +>]
|
||||
::
|
||||
++ coup-drum-phat (wrap take-coup-phat):from-drum
|
||||
++ coup-helm-hi (wrap coup-hi):from-helm
|
||||
++ diff-sole-effect-drum-phat (wrap diff-sole-effect-phat):from-drum
|
||||
@ -72,41 +77,45 @@
|
||||
++ from-helm (from-lib %helm [..$ ,_abet]:(helm))
|
||||
++ from-kiln (from-lib %kiln [..$ ,_abet]:(kiln))
|
||||
::
|
||||
++ init-helm |=([way=wire *] [~ +>])
|
||||
++ made-kiln (wrap take-made):from-kiln
|
||||
++ mere-kiln (wrap take-mere):from-kiln
|
||||
++ mere-kiln-sync (wrap take-mere-sync):from-kiln
|
||||
++ note-helm (wrap take-note):from-helm
|
||||
++ onto-drum (wrap take-onto):from-drum
|
||||
++ peer-drum (wrap peer):from-drum
|
||||
++ poke-dill-belt (wrap poke-dill-belt):from-drum
|
||||
++ poke-drum-link (wrap poke-link):from-drum
|
||||
::++ poke-drum-exit (wrap poke-exit):from-drum
|
||||
++ poke-drum-start (wrap poke-start):from-drum
|
||||
++ poke-helm-hi (wrap poke-hi):from-helm
|
||||
++ poke-helm-init (wrap poke-init):from-helm
|
||||
++ poke-helm-invite (wrap poke-invite):from-helm
|
||||
++ poke-helm-mass (wrap poke-mass):from-helm
|
||||
++ poke-helm-reload (wrap poke-reload):from-helm
|
||||
++ poke-helm-reload-desk (wrap poke-reload-desk):from-helm
|
||||
++ poke-helm-reset (wrap poke-reset):from-helm
|
||||
++ poke-helm-send-hi (wrap poke-send-hi):from-helm
|
||||
++ poke-helm-verb (wrap poke-verb):from-helm
|
||||
++ poke-helm-begin (wrap poke-begin):from-helm
|
||||
++ poke-hood-sync (wrap poke-sync):from-kiln
|
||||
++ poke-kiln-cp (wrap poke-cp):from-kiln
|
||||
++ poke-kiln-label (wrap poke-label):from-kiln
|
||||
++ poke-kiln-merge (wrap poke-merge):from-kiln
|
||||
++ poke-kiln-mount (wrap poke-mount):from-kiln
|
||||
++ poke-kiln-mv (wrap poke-mv):from-kiln
|
||||
++ poke-kiln-rm (wrap poke-rm):from-kiln
|
||||
++ poke-kiln-schedule (wrap poke-schedule):from-kiln
|
||||
++ poke-kiln-sync (wrap poke-sync):from-kiln
|
||||
++ poke-kiln-unmount (wrap poke-unmount):from-kiln
|
||||
++ poke-kiln-unsync (wrap poke-unsync):from-kiln
|
||||
++ poke-will (wrap poke-will):from-helm
|
||||
++ quit-drum-phat (wrap quit-phat):from-drum
|
||||
++ reap-drum-phat (wrap reap-phat):from-drum
|
||||
++ woot-helm (wrap take-woot):from-helm
|
||||
++ writ-kiln-sync (wrap take-writ):from-kiln
|
||||
++ init-helm |=([way=wire *] [~ +>])
|
||||
++ made-kiln (wrap take-made):from-kiln
|
||||
++ mere-kiln (wrap take-mere):from-kiln
|
||||
++ mere-kiln-sync (wrap take-mere-sync):from-kiln
|
||||
++ note-helm (wrap take-note):from-helm
|
||||
++ onto-drum (wrap take-onto):from-drum
|
||||
++ peer-drum (wrap peer):from-drum
|
||||
++ poke-dill-belt (wrap poke-dill-belt):from-drum
|
||||
++ poke-drum-link (wrap poke-link):from-drum
|
||||
::++ poke-drum-exit (wrap poke-exit):from-drum
|
||||
++ poke-drum-start (wrap poke-start):from-drum
|
||||
++ poke-helm-hi (wrap poke-hi):from-helm
|
||||
++ poke-helm-init (wrap poke-init):from-helm
|
||||
++ poke-helm-invite (wrap poke-invite):from-helm
|
||||
++ poke-helm-mass (wrap poke-mass):from-helm
|
||||
++ poke-helm-reload (wrap poke-reload):from-helm
|
||||
++ poke-helm-reload-desk (wrap poke-reload-desk):from-helm
|
||||
++ poke-helm-reset (wrap poke-reset):from-helm
|
||||
++ poke-helm-send-hi (wrap poke-send-hi):from-helm
|
||||
++ poke-helm-verb (wrap poke-verb):from-helm
|
||||
++ poke-helm-begin (wrap poke-begin):from-helm
|
||||
++ poke-hood-sync (wrap poke-sync):from-kiln
|
||||
++ poke-kiln-cp (wrap poke-cp):from-kiln
|
||||
++ poke-kiln-label (wrap poke-label):from-kiln
|
||||
++ poke-kiln-merge (wrap poke-merge):from-kiln
|
||||
++ poke-kiln-cancel (wrap poke-cancel):from-kiln
|
||||
++ poke-kiln-mount (wrap poke-mount):from-kiln
|
||||
++ poke-kiln-mv (wrap poke-mv):from-kiln
|
||||
++ poke-kiln-rm (wrap poke-rm):from-kiln
|
||||
++ poke-kiln-schedule (wrap poke-schedule):from-kiln
|
||||
++ poke-kiln-sync (wrap poke-sync):from-kiln
|
||||
++ poke-kiln-start-autoload (wrap poke-start-autoload):from-kiln
|
||||
++ poke-kiln-autoload (wrap poke-autoload):from-kiln
|
||||
++ poke-kiln-unmount (wrap poke-unmount):from-kiln
|
||||
++ poke-kiln-unsync (wrap poke-unsync):from-kiln
|
||||
++ poke-will (wrap poke-will):from-helm
|
||||
++ quit-drum-phat (wrap quit-phat):from-drum
|
||||
++ reap-drum-phat (wrap reap-phat):from-drum
|
||||
++ woot-helm (wrap take-woot):from-helm
|
||||
++ writ-kiln-autoload (wrap take-writ-autoload):from-kiln
|
||||
++ writ-kiln-sync (wrap take-writ-sync):from-kiln
|
||||
--
|
||||
|
550
arvo/clay.hoon
550
arvo/clay.hoon
@ -162,11 +162,7 @@
|
||||
mer=mer.jod
|
||||
==
|
||||
=* red ->
|
||||
=| yel=(list ,[p=duct q=gift])
|
||||
=| byn=(list ,[p=duct q=riot])
|
||||
=| reg=(list ,[p=duct q=gift])
|
||||
=| say=(list ,[p=duct q=path r=ship s=[p=@ud q=riff]])
|
||||
=| tag=(list move)
|
||||
=| mow=(list move)
|
||||
|%
|
||||
++ abet
|
||||
^- [(list move) raft]
|
||||
@ -176,23 +172,7 @@
|
||||
ruf(hoy (~(put by hoy.ruf) her rug))
|
||||
=+ dos=(~(put by dos.u.rom) syd [qyx dom dok mer])
|
||||
ruf(fat (~(put by fat.ruf) her [(need hun) dos]))
|
||||
;: weld
|
||||
%+ turn (flop yel)
|
||||
|=([a=duct b=gift] [(need hun) %give b])
|
||||
::
|
||||
%+ turn (flop reg)
|
||||
|=([a=duct b=gift] [a %give b])
|
||||
::
|
||||
%+ turn (flop byn)
|
||||
|=([a=duct b=riot] [a %give [%writ b]])
|
||||
::
|
||||
%+ turn (flop say)
|
||||
|= [a=duct b=path c=ship d=[p=@ud q=riff]]
|
||||
:- a
|
||||
[%pass b %a %wont [our c] [%c %question p.q.d (scot %ud p.d) ~] q.d]
|
||||
::
|
||||
tag
|
||||
==
|
||||
(flop mow)
|
||||
::
|
||||
++ aver :: read
|
||||
|= mun=mood
|
||||
@ -260,6 +240,14 @@
|
||||
(mule |.(`~`~|([%expected-path got=p.pax] !!)))
|
||||
$(tay t.tay, can (~(put by can) ((hard path) q.q.pax) q.i.tay))
|
||||
::
|
||||
++ emit
|
||||
|= mof=move
|
||||
%_(+> mow [mof mow])
|
||||
::
|
||||
++ emil
|
||||
|= mof=(list move)
|
||||
%_(+> mow (welp mof mow))
|
||||
::
|
||||
++ balk :: read and send
|
||||
|= [hen=duct cay=(unit (each cage lobe)) mun=mood]
|
||||
^+ +>
|
||||
@ -268,18 +256,18 @@
|
||||
::
|
||||
++ bait
|
||||
|= [hen=duct tym=@da]
|
||||
%_(+> tag :_(tag [hen %pass /tyme %t %wait tym]))
|
||||
(emit hen %pass /tyme %t %wait tym)
|
||||
::
|
||||
++ best
|
||||
|= [hen=duct tym=@da]
|
||||
%_(+> tag :_(tag [hen %pass /tyme %t %rest tym]))
|
||||
(emit hen %pass /tyme %t %rest tym)
|
||||
::
|
||||
++ blab :: ship result
|
||||
|= [hen=duct mun=mood dat=(each cage lobe)]
|
||||
^+ +>
|
||||
?: ?=(%& -.dat)
|
||||
+>.$(byn [[hen ~ [p.mun q.mun syd] r.mun p.dat] byn])
|
||||
=- +>.$(tag [- tag])
|
||||
(emit hen %give %writ ~ [p.mun q.mun syd] r.mun p.dat)
|
||||
%- emit
|
||||
:* hen %pass [%blab p.mun (scot q.mun) syd r.mun]
|
||||
%f %exec our ~ [her syd q.mun] (lobe-to-silk:ze r.mun p.dat)
|
||||
==
|
||||
@ -295,7 +283,15 @@
|
||||
::
|
||||
++ blub :: ship stop
|
||||
|= hen=duct
|
||||
%_(+> byn [[hen ~] byn])
|
||||
(emit hen %give %writ ~)
|
||||
::
|
||||
++ print-to-dill
|
||||
|= [car=@tD tan=tank]
|
||||
(emit (need hun) %give %note car tan)
|
||||
::
|
||||
++ send-over-ames
|
||||
|= [a=duct b=path c=ship d=[p=@ud q=riff]]
|
||||
(emit a %pass b %a %wont [our c] [%c %question p.q.d (scot %ud p.d) ~] q.d)
|
||||
::
|
||||
++ duce :: produce request
|
||||
|= rov=rove
|
||||
@ -309,8 +305,10 @@
|
||||
?. ?=([%sing %v *] rav) rav
|
||||
[%many %| [%ud let.dom] `case`q.p.rav r.p.rav]
|
||||
=+ inx=nix.u.ref
|
||||
=. +>+.$
|
||||
=< ?>(?=(^ ref) .)
|
||||
(send-over-ames hen [(scot %ud inx) ~] her inx syd ~ vaw)
|
||||
%= +>+.$
|
||||
say [[hen [(scot %ud inx) ~] her [inx syd ~ vaw]] say]
|
||||
nix.u.ref +(nix.u.ref)
|
||||
bom.u.ref (~(put by bom.u.ref) inx [hen vaw])
|
||||
fod.u.ref (~(put by fod.u.ref) hen inx)
|
||||
@ -335,22 +333,19 @@
|
||||
=+ mus=(skim can |=(paf=path =(pax (scag (lent pax) paf))))
|
||||
?~ mus
|
||||
+>.$
|
||||
%_ +>.$
|
||||
tag
|
||||
:_ tag
|
||||
:* hen %pass [%ergoing (scot %p her) syd ~] %f
|
||||
%exec our ~ [her syd %da now] %tabl
|
||||
^- (list (pair silk silk))
|
||||
%+ turn `(list path)`mus
|
||||
|= a=path
|
||||
^- (pair silk silk)
|
||||
:- [%$ %path !>(a)]
|
||||
:+ %cast %mime
|
||||
=+ (need (need (read-x:ze let.dom a)))
|
||||
?: ?=(%& -<)
|
||||
[%$ p.-]
|
||||
(lobe-to-silk:ze a p.-)
|
||||
==
|
||||
%- emit
|
||||
:* hen %pass [%ergoing (scot %p her) syd ~] %f
|
||||
%exec our ~ [her syd %da now] %tabl
|
||||
^- (list (pair silk silk))
|
||||
%+ turn `(list path)`mus
|
||||
|= a=path
|
||||
^- (pair silk silk)
|
||||
:- [%$ %path !>(a)]
|
||||
:+ %cast %mime
|
||||
=+ (need (need (read-x:ze let.dom a)))
|
||||
?: ?=(%& -<)
|
||||
[%$ p.-]
|
||||
(lobe-to-silk:ze a p.-)
|
||||
==
|
||||
::
|
||||
++ ease :: release request
|
||||
@ -364,8 +359,10 @@
|
||||
|- ^+ +.$
|
||||
=+ nux=(~(get by fod.u.ref) hen)
|
||||
?~ nux +.$
|
||||
=. +.$
|
||||
=< ?>(?=(^ ref) .)
|
||||
(send-over-ames hen [(scot %ud u.nux) ~] her u.nux syd ~)
|
||||
%= +.$
|
||||
say [[hen [(scot %ud u.nux) ~] her [u.nux syd ~]] say]
|
||||
fod.u.ref (~(del by fod.u.ref) hen)
|
||||
bom.u.ref (~(del by bom.u.ref) u.nux)
|
||||
==
|
||||
@ -422,31 +419,19 @@
|
||||
(duce `rove`[%many p.rav ptr q.q.rav r.q.rav ear])
|
||||
==
|
||||
::
|
||||
++ echa :: announce raw
|
||||
|= [wen=@da mer=mizu]
|
||||
^+ +>
|
||||
%= +>
|
||||
reg ~& %merge-announce reg
|
||||
:: yel [[hen %note '=' %leaf ~] yel] :: XX do better
|
||||
==
|
||||
::
|
||||
++ echo :: announce changes
|
||||
|= [wen=@da lem=nuri]
|
||||
^+ +>
|
||||
%_ +>.$
|
||||
yel
|
||||
=+ pre=`path`~[(scot %p her) syd (scot %ud let.dom)]
|
||||
?- -.lem
|
||||
| :_ yel
|
||||
[hen %note '=' %leaf :(weld (trip p.lem) " " (spud pre))]
|
||||
& |- ^+ yel
|
||||
?~ p.lem yel
|
||||
:_ $(p.lem t.p.lem)
|
||||
:- hen
|
||||
:+ %note
|
||||
?-(-.q.i.p.lem %del '-', %ins '+', %dif ':')
|
||||
[%leaf (spud (weld pre p.i.p.lem))]
|
||||
==
|
||||
=+ pre=`path`~[(scot %p her) syd (scot %ud let.dom)]
|
||||
?- -.lem
|
||||
| (print-to-dill '=' %leaf :(weld (trip p.lem) " " (spud pre)))
|
||||
& |- ^+ +>.^$
|
||||
?~ p.lem +>.^$
|
||||
=. +>.^$
|
||||
%+ print-to-dill
|
||||
?-(-.q.i.p.lem %del '-', %ins '+', %dif ':')
|
||||
[%leaf (spud (weld pre p.i.p.lem))]
|
||||
$(p.lem t.p.lem)
|
||||
==
|
||||
::
|
||||
++ edit :: apply changes
|
||||
@ -472,107 +457,97 @@
|
||||
?& ?=([?(%hoon %hook) *] (flop pax))
|
||||
?=(%mime p.p.mis)
|
||||
==
|
||||
=- %_ +>.$
|
||||
tag (welp - tag)
|
||||
dok
|
||||
:- ~
|
||||
:* %+ turn del
|
||||
=. +>.$
|
||||
%- emil
|
||||
^- (list move)
|
||||
:~ :* hen %pass
|
||||
[%inserting (scot %p her) syd (scot %da wen) ~]
|
||||
%f %exec our ~ [her syd %da wen] %tabl
|
||||
^- (list (pair silk silk))
|
||||
%+ turn ins
|
||||
|= [pax=path mis=miso]
|
||||
?> ?=(%del -.mis)
|
||||
pax
|
||||
::
|
||||
%+ turn ink
|
||||
|= [pax=path mis=miso]
|
||||
^- (pair path cage)
|
||||
?> ?=(%ins -.mis)
|
||||
:- [%$ %path -:!>(*path) pax]
|
||||
=+ =>((flop pax) ?~(. %$ i))
|
||||
[pax - [%atom %t] ((hard ,@t) +>.q.q.p.mis)]
|
||||
::
|
||||
~
|
||||
::
|
||||
%- mo
|
||||
[%cast - [%$ p.mis]]
|
||||
==
|
||||
:* hen %pass
|
||||
[%diffing (scot %p her) syd (scot %da wen) ~]
|
||||
%f %exec our ~ [her syd %da wen] %tabl
|
||||
^- (list (pair silk silk))
|
||||
%+ turn dif
|
||||
|= [pax=path mis=miso]
|
||||
?> ?=(%dif -.mis)
|
||||
[pax p.mis]
|
||||
::
|
||||
~
|
||||
::
|
||||
%- mo
|
||||
=+ (need (need (read-x:ze let.dom pax)))
|
||||
?> ?=(%& -<)
|
||||
:- [%$ %path -:!>(*path) pax]
|
||||
[%pact [%$ p.-] [%$ p.mis]]
|
||||
==
|
||||
:* hen %pass
|
||||
[%castifying (scot %p her) syd (scot %da wen) ~]
|
||||
%f %exec our ~ [her syd %da wen] %tabl
|
||||
^- (list (pair silk silk))
|
||||
%+ turn mut
|
||||
|= [pax=path mis=miso]
|
||||
?> ?=(%mut -.mis)
|
||||
[pax p.mis]
|
||||
::
|
||||
~
|
||||
::
|
||||
~
|
||||
::
|
||||
%- mo ^- (list (pair path mime))
|
||||
;: welp
|
||||
^- (list (pair path mime))
|
||||
%+ murn ins
|
||||
|= [pax=path mis=miso]
|
||||
^- (unit (pair path mime))
|
||||
?> ?=(%ins -.mis)
|
||||
?. ?=(%mime p.p.mis)
|
||||
~
|
||||
`[pax ((hard mime) q.q.p.mis)]
|
||||
::
|
||||
^- (list (pair path mime))
|
||||
%+ murn ink
|
||||
|= [pax=path mis=miso]
|
||||
^- (unit (pair path mime))
|
||||
?> ?=(%ins -.mis)
|
||||
?> ?=(%mime p.p.mis)
|
||||
`[pax ((hard mime) q.q.p.mis)]
|
||||
::
|
||||
^- (list (pair path mime))
|
||||
%+ murn mut
|
||||
|= [pax=path mis=miso]
|
||||
^- (unit (pair path mime))
|
||||
?> ?=(%mut -.mis)
|
||||
?. ?=(%mime p.p.mis)
|
||||
~
|
||||
`[pax ((hard mime) q.q.p.mis)]
|
||||
==
|
||||
:- [%$ %path -:!>(*path) pax]
|
||||
=+ (lobe-to-mark:ze (~(got by q:(aeon-to-yaki:ze let.dom)) pax))
|
||||
[%cast - [%$ p.mis]]
|
||||
==
|
||||
==
|
||||
^- (list move)
|
||||
:~ :* hen %pass
|
||||
[%inserting (scot %p her) syd (scot %da wen) ~]
|
||||
%f %exec our ~ [her syd %da wen] %tabl
|
||||
^- (list (pair silk silk))
|
||||
%+ turn ins
|
||||
==
|
||||
%_ +>.$
|
||||
dok
|
||||
:- ~
|
||||
:* (turn del |=([pax=path mis=miso] ?>(?=(%del -.mis) pax)))
|
||||
::
|
||||
%+ turn ink
|
||||
|= [pax=path mis=miso]
|
||||
^- (pair path cage)
|
||||
?> ?=(%ins -.mis)
|
||||
=+ =>((flop pax) ?~(. %$ i))
|
||||
[pax - [%atom %t] ((hard ,@t) +>.q.q.p.mis)]
|
||||
::
|
||||
~
|
||||
::
|
||||
(mo (turn dif |=([pax=path mis=miso] ?>(?=(%dif -.mis) [pax p.mis]))))
|
||||
::
|
||||
~
|
||||
::
|
||||
(mo (turn mut |=([pax=path mis=miso] ?>(?=(%mut -.mis) [pax p.mis]))))
|
||||
::
|
||||
~
|
||||
::
|
||||
~
|
||||
::
|
||||
%- mo ^- (list (pair path mime))
|
||||
;: welp
|
||||
^- (list (pair path mime))
|
||||
%+ murn ins
|
||||
|= [pax=path mis=miso]
|
||||
^- (unit (pair path mime))
|
||||
?> ?=(%ins -.mis)
|
||||
:- [%$ %path -:!>(*path) pax]
|
||||
=+ =>((flop pax) ?~(. %$ i))
|
||||
[%cast - [%$ p.mis]]
|
||||
==
|
||||
:* hen %pass
|
||||
[%diffing (scot %p her) syd (scot %da wen) ~]
|
||||
%f %exec our ~ [her syd %da wen] %tabl
|
||||
^- (list (pair silk silk))
|
||||
%+ turn dif
|
||||
?. ?=(%mime p.p.mis)
|
||||
~
|
||||
`[pax ((hard mime) q.q.p.mis)]
|
||||
::
|
||||
^- (list (pair path mime))
|
||||
%+ murn ink
|
||||
|= [pax=path mis=miso]
|
||||
?> ?=(%dif -.mis)
|
||||
=+ (need (need (read-x:ze let.dom pax)))
|
||||
?> ?=(%& -<)
|
||||
:- [%$ %path -:!>(*path) pax]
|
||||
[%pact [%$ p.-] [%$ p.mis]]
|
||||
==
|
||||
:* hen %pass
|
||||
[%castifying (scot %p her) syd (scot %da wen) ~]
|
||||
%f %exec our ~ [her syd %da wen] %tabl
|
||||
^- (list (pair silk silk))
|
||||
%+ turn mut
|
||||
^- (unit (pair path mime))
|
||||
?> ?=(%ins -.mis)
|
||||
?> ?=(%mime p.p.mis)
|
||||
`[pax ((hard mime) q.q.p.mis)]
|
||||
::
|
||||
^- (list (pair path mime))
|
||||
%+ murn mut
|
||||
|= [pax=path mis=miso]
|
||||
^- (unit (pair path mime))
|
||||
?> ?=(%mut -.mis)
|
||||
:- [%$ %path -:!>(*path) pax]
|
||||
=+ (lobe-to-mark:ze (~(got by q:(aeon-to-yaki:ze let.dom)) pax))
|
||||
[%cast - [%$ p.mis]]
|
||||
==
|
||||
?. ?=(%mime p.p.mis)
|
||||
~
|
||||
`[pax ((hard mime) q.q.p.mis)]
|
||||
==
|
||||
==
|
||||
==
|
||||
::
|
||||
++ silkify
|
||||
@ -691,8 +666,7 @@
|
||||
%+ turn cat
|
||||
|= [pax=path cay=cage]
|
||||
[pax (page-to-lobe:ze [p q.q]:cay)]
|
||||
=- %_(+>.$ tag [- tag])
|
||||
^- move
|
||||
%- emit
|
||||
:* hen %pass
|
||||
[%mutating (scot %p her) syd (scot %da wen) ~]
|
||||
%f %exec our ~ [her syd %da wen] %tabl
|
||||
@ -733,11 +707,8 @@
|
||||
^+ +>
|
||||
:: ~& %taking-patch
|
||||
?: ?=(%| -.res)
|
||||
%_ +>.$
|
||||
dok ~
|
||||
yel
|
||||
[[hen %note '!' %rose [" " "" ""] leaf/"clay patch failed" p.res] yel]
|
||||
==
|
||||
=. dok ~
|
||||
(print-to-dill '!' %rose [" " "" ""] leaf/"clay patch failed" p.res)
|
||||
:: ~& %editing
|
||||
=+ ^- sim=(list (pair path misu))
|
||||
?~ dok
|
||||
@ -795,38 +766,31 @@
|
||||
=+ can=(mo sim)
|
||||
:: ~& %forming-ergo
|
||||
:: =- ~& %formed-ergo -
|
||||
%_ +>.$
|
||||
dok ~
|
||||
tag
|
||||
:_ tag
|
||||
:* hen %pass [%ergoing (scot %p her) syd ~] %f
|
||||
%exec our ~ [her syd %da now] %tabl
|
||||
^- (list (pair silk silk))
|
||||
%+ turn (~(tap in sum))
|
||||
|= a=path
|
||||
^- (pair silk silk)
|
||||
:- [%$ %path !>(a)]
|
||||
=+ b=(~(got by can) a)
|
||||
?: ?=(%del -.b)
|
||||
[%$ %null !>(~)]
|
||||
=+ (~(get by mim.u.dok) a)
|
||||
?^ - [%$ %mime !>(u.-)]
|
||||
:+ %cast %mime
|
||||
=+ (need (need (read-x:ze let.dom a)))
|
||||
?: ?=(%& -<)
|
||||
[%$ p.-]
|
||||
(lobe-to-silk:ze a p.-)
|
||||
==
|
||||
%- emit(dok ~)
|
||||
:* hen %pass [%ergoing (scot %p her) syd ~] %f
|
||||
%exec our ~ [her syd %da now] %tabl
|
||||
^- (list (pair silk silk))
|
||||
%+ turn (~(tap in sum))
|
||||
|= a=path
|
||||
^- (pair silk silk)
|
||||
:- [%$ %path !>(a)]
|
||||
=+ b=(~(got by can) a)
|
||||
?: ?=(%del -.b)
|
||||
[%$ %null !>(~)]
|
||||
=+ (~(get by mim.u.dok) a)
|
||||
?^ - [%$ %mime !>(u.-)]
|
||||
:+ %cast %mime
|
||||
=+ (need (need (read-x:ze let.dom a)))
|
||||
?: ?=(%& -<)
|
||||
[%$ p.-]
|
||||
(lobe-to-silk:ze a p.-)
|
||||
==
|
||||
::
|
||||
++ take-ergo
|
||||
|= res=gage
|
||||
^+ +>
|
||||
?: ?=(%| -.res)
|
||||
%_ +>.$
|
||||
yel
|
||||
[[hen %note '!' %rose [" " "" ""] leaf/"clay ergo failed" p.res] yel]
|
||||
==
|
||||
(print-to-dill '!' %rose [" " "" ""] leaf/"clay ergo failed" p.res)
|
||||
?~ hez ~|(%no-sync-duct !!)
|
||||
=+ ^- can=(map path (unit mime))
|
||||
%- mo ^- mode
|
||||
@ -839,33 +803,27 @@
|
||||
~
|
||||
`((hard mime) q.q.mim)
|
||||
=+ mus=(must-ergo (turn (~(tap by can)) head))
|
||||
%= +>.$
|
||||
reg
|
||||
%- welp :_ reg
|
||||
%+ turn (~(tap by mus))
|
||||
|= [pot=term len=@ud pak=(set path)]
|
||||
:* u.hez %ergo pot
|
||||
%+ turn (~(tap in pak))
|
||||
|= pax=path
|
||||
[(slag len pax) (~(got by can) pax)]
|
||||
==
|
||||
%- emil
|
||||
%+ turn (~(tap by mus))
|
||||
|= [pot=term len=@ud pak=(set path)]
|
||||
:* u.hez %give %ergo pot
|
||||
%+ turn (~(tap in pak))
|
||||
|= pax=path
|
||||
[(slag len pax) (~(got by can) pax)]
|
||||
==
|
||||
::
|
||||
++ checkout-ankh
|
||||
|= hat=(map path lobe)
|
||||
^+ +>
|
||||
%_ +>.$
|
||||
tag
|
||||
:_ tag
|
||||
:* hen %pass [%patching (scot %p her) syd ~] %f
|
||||
%exec our :^ ~ [her syd %da now] %tabl
|
||||
^- (list (pair silk silk))
|
||||
%+ turn (~(tap by hat))
|
||||
|= [a=path b=lobe]
|
||||
^- (pair silk silk)
|
||||
:- [%$ %path-hash !>([a b])]
|
||||
(lobe-to-silk:ze a b)
|
||||
==
|
||||
%- emit
|
||||
:* hen %pass [%patching (scot %p her) syd ~] %f
|
||||
%exec our :^ ~ [her syd %da now] %tabl
|
||||
^- (list (pair silk silk))
|
||||
%+ turn (~(tap by hat))
|
||||
|= [a=path b=lobe]
|
||||
^- (pair silk silk)
|
||||
:- [%$ %path-hash !>([a b])]
|
||||
(lobe-to-silk:ze a b)
|
||||
==
|
||||
::
|
||||
++ apply-foreign-update :: apply subscription
|
||||
@ -1016,34 +974,10 @@
|
||||
!!
|
||||
==
|
||||
::
|
||||
++ rand-to-rant
|
||||
|= rut=rand
|
||||
^+ +>
|
||||
~| [%x-over-network-not-implemented [p q -.r]:rut hen] !!
|
||||
:: =- %_(+>.$ tag [- tag])
|
||||
:: :* hen
|
||||
:: [%foreign-plops (scot %p our) (scot %p her) syd ~]
|
||||
:: %f %exec our ~ %tabl
|
||||
:: ^- (list (pair silk silk))
|
||||
:: %+ turn (~(tap in pop))
|
||||
:: |= a=plop
|
||||
:: ?- -.a
|
||||
:: %delta
|
||||
:: :- [%$ %blob !>([%delta p.a q.a *cage])]
|
||||
:: [%vale p.r.a q.r.a]
|
||||
:: ::
|
||||
:: %direct
|
||||
:: :- [%$ %blob !>([%direct p.a *cage])]
|
||||
:: [%vale p.q.a q.q.a]
|
||||
:: ::
|
||||
:: %indirect ~| %foreign-indirect-not-implemented !!
|
||||
:: ==
|
||||
:: ==
|
||||
::
|
||||
++ validate-x
|
||||
|= [car=care cas=case pax=path peg=page]
|
||||
^+ +>
|
||||
=- %_(+>.$ tag [- tag])
|
||||
%- emit
|
||||
:* hen %pass
|
||||
[%foreign-x (scot %p our) (scot %p her) syd car (scot cas) pax]
|
||||
%f %exec our ~ [her syd cas]
|
||||
@ -1065,8 +999,8 @@
|
||||
++ validate-plops
|
||||
|= [cas=case lem=(unit ,@da) pop=(set plop)]
|
||||
^+ +>
|
||||
=- %_(+>.$ tag [- tag])
|
||||
=+ lum=(scot %da (fall lem *@da))
|
||||
%- emit
|
||||
:* hen %pass
|
||||
[%foreign-plops (scot %p our) (scot %p her) syd lum ~]
|
||||
%f %exec our ~ [her syd cas] %tabl
|
||||
@ -1074,15 +1008,8 @@
|
||||
%+ turn (~(tap in pop))
|
||||
|= a=plop
|
||||
?- -.a
|
||||
%delta
|
||||
:- [%$ %blob !>([%delta p.a q.a *page])]
|
||||
[%vale p.r.a q.r.a]
|
||||
::
|
||||
%direct
|
||||
:- [%$ %blob !>([%direct p.a *page])]
|
||||
[%vale p.q.a q.q.a]
|
||||
::
|
||||
%indirect ~| %foreign-indirect-not-implemented !!
|
||||
%delta [[%$ %blob !>([%delta p.a q.a *page])] [%vale p.r.a q.r.a]]
|
||||
%direct [[%$ %blob !>([%direct p.a *page])] [%vale p.q.a q.q.a]]
|
||||
==
|
||||
==
|
||||
::
|
||||
@ -1101,7 +1028,6 @@
|
||||
?- -.bol
|
||||
%delta [-.bol p.bol q.bol p.cay q.q.cay]
|
||||
%direct [-.bol p.bol p.cay q.q.cay]
|
||||
%indirect ~| %plop-indirect-not-implemented !!
|
||||
==
|
||||
%^ apply-foreign-update
|
||||
lem
|
||||
@ -1219,6 +1145,15 @@
|
||||
(bleb p.i.xiq +(u.nab) ?:(p.q.i.xiq ~ `[u.nab u.huy]))
|
||||
==
|
||||
==
|
||||
++ drop-me
|
||||
^+ .
|
||||
?~ mer
|
||||
.
|
||||
%- emit(mer ~) ^- move :*
|
||||
hen.u.mer %give %mere %| %user-interrupt
|
||||
>sor.u.mer< >our< >cas.u.mer< >gem.u.mer< ~
|
||||
==
|
||||
::
|
||||
++ ze
|
||||
|%
|
||||
++ aeon-to-tako ~(got by hit.dom)
|
||||
@ -1231,7 +1166,6 @@
|
||||
?- -
|
||||
%delta p.q
|
||||
%direct p.q
|
||||
%indirect p.q
|
||||
==
|
||||
++ lobe-to-silk :: XX maybe move hoo{n,k} stuff here
|
||||
|= [pax=path lob=lobe]
|
||||
@ -1249,7 +1183,6 @@
|
||||
=+ bol=(~(got by lat.ran) lob)
|
||||
?- -.bol
|
||||
%direct [%volt q.bol]
|
||||
%indirect [%volt q.bol]
|
||||
%delta ~| delta/q.q.bol
|
||||
[%pact $(lob q.q.bol) [%volt r.bol]]
|
||||
==
|
||||
@ -1482,7 +1415,6 @@
|
||||
?- -.gar
|
||||
%direct (~(put in far) lob)
|
||||
%delta (~(put in $(lob q.q.gar)) lob)
|
||||
%indirect (~(put in $(lob r.gar)) lob)
|
||||
==
|
||||
::
|
||||
++ data-twixt-takos
|
||||
@ -1530,6 +1462,15 @@
|
||||
~
|
||||
```[%null [%atom %n] ~]
|
||||
::
|
||||
++ read-v
|
||||
|= [yon=aeon pax=path]
|
||||
^- (unit (unit ,[%dome (hypo dome)]))
|
||||
?: (lth yon let.dom)
|
||||
~
|
||||
?: (gth yon let.dom)
|
||||
`~
|
||||
``[%dome -:!>(*dome) dom]
|
||||
::
|
||||
++ read-x
|
||||
|= [yon=aeon pax=path]
|
||||
^- (unit (unit (each cage lobe)))
|
||||
@ -1556,8 +1497,6 @@
|
||||
=+ bol=(lobe-to-blob u.lob)
|
||||
?: ?=(%direct -.bol)
|
||||
((hard ,@t) q.q.bol)
|
||||
?: ?=(%indirect -.bol)
|
||||
((hard ,@t) q.q.bol)
|
||||
?> ?=(%delta -.bol)
|
||||
=+ txt=$(u.lob q.q.bol)
|
||||
?> ?=(%txt-diff p.r.bol)
|
||||
@ -1611,6 +1550,8 @@
|
||||
?^(r.mun [~ ~] [~ ~ %& %aeon !>(yon)])
|
||||
?: ?=(%u p.mun)
|
||||
(read-u yon r.mun)
|
||||
?: ?=(%v p.mun)
|
||||
(bind (read-v yon r.mun) (curr bind (cury same %&)))
|
||||
?: ?=(%x p.mun)
|
||||
(read-x yon r.mun)
|
||||
?: ?=(%y p.mun)
|
||||
@ -1645,7 +1586,7 @@
|
||||
:: %- ~(run by hat)
|
||||
:: |= a=lobe
|
||||
:: =+ (lobe-to-blob a)
|
||||
:: ?-(-.- %direct q.-, %indirect q.-, %delta !!)
|
||||
:: ?-(-.- %direct q.-, %delta !!)
|
||||
::`+>.$(ank.dom (checkout-ankh -), let.dom yon)
|
||||
::
|
||||
++ update-lat :: update-lat:ze
|
||||
@ -1716,7 +1657,17 @@
|
||||
^+ ..me
|
||||
?: don
|
||||
..me(mer `dat)
|
||||
..me(mer ~, reg :_(reg [hen %mere gon.dat]))
|
||||
=. mer ~
|
||||
=> (emit hen.dat %give %mere gon.dat)
|
||||
..me
|
||||
::
|
||||
++ emit
|
||||
|= move
|
||||
%_(+> ..ze (^emit +<))
|
||||
::
|
||||
++ emil
|
||||
|= (list move)
|
||||
%_(+> ..ze (^emil +<))
|
||||
::
|
||||
++ route
|
||||
|= [sat=term res=(each riot gage)]
|
||||
@ -1759,7 +1710,7 @@
|
||||
::
|
||||
++ fetch-ali
|
||||
^+ .
|
||||
=- %_(+ tag [- tag], wat.dat %ali)
|
||||
%- emit(wat.dat %ali)
|
||||
:* hen %pass
|
||||
[%merge (scot %p p.bob) q.bob (scot %p p.ali) q.ali %ali ~]
|
||||
%c %warp [p.bob p.ali] q.ali
|
||||
@ -1937,7 +1888,7 @@
|
||||
++ diff-bas
|
||||
|= [nam=term yak=yaki oth=(trel ship desk case) yuk=yaki]
|
||||
^+ +>
|
||||
=- %_(+>.$ tag [- tag])
|
||||
%- emit
|
||||
:* hen %pass
|
||||
=+ (cat 3 %diff- nam)
|
||||
[%merge (scot %p p.bob) q.bob (scot %p p.ali) q.ali - ~]
|
||||
@ -1982,15 +1933,18 @@
|
||||
|= [pax=path lob=lobe]
|
||||
(~(has by q.bas.dat) pax)
|
||||
=. cal.dal.dat
|
||||
%- mo
|
||||
%+ skim (~(tap by q.bas.dat))
|
||||
%- mo ^- (list (pair path lobe))
|
||||
%+ murn (~(tap by q.bas.dat))
|
||||
|= [pax=path lob=lobe]
|
||||
^- (unit (pair path lobe))
|
||||
=+ a=(~(get by q.ali.dat) pax)
|
||||
=+ b=(~(get by q.bob.dat) pax)
|
||||
?& ?=(^ a)
|
||||
!=([~ lob] a)
|
||||
=([~ lob] b)
|
||||
==
|
||||
?. ?& ?=(^ a)
|
||||
!=([~ lob] a)
|
||||
=([~ lob] b)
|
||||
==
|
||||
~
|
||||
`[pax +.a]
|
||||
=. can.dal.dat p.can
|
||||
=. old.dal.dat
|
||||
%- mo ^- (list ,[path ~])
|
||||
@ -2022,15 +1976,18 @@
|
||||
|= [pax=path lob=lobe]
|
||||
(~(has by q.bas.dat) pax)
|
||||
=. cal.dob.dat
|
||||
%- mo
|
||||
%+ skim (~(tap by q.bas.dat))
|
||||
%- mo ^- (list (pair path lobe))
|
||||
%+ murn (~(tap by q.bas.dat))
|
||||
|= [pax=path lob=lobe]
|
||||
^- (unit (pair path lobe))
|
||||
=+ a=(~(get by q.ali.dat) pax)
|
||||
=+ b=(~(get by q.bob.dat) pax)
|
||||
?& ?=(^ b)
|
||||
!=([~ lob] b)
|
||||
=([~ lob] a)
|
||||
==
|
||||
?. ?& ?=(^ b)
|
||||
!=([~ lob] b)
|
||||
=([~ lob] a)
|
||||
==
|
||||
~
|
||||
`[pax +.b]
|
||||
=. can.dob.dat p.can
|
||||
=. old.dob.dat
|
||||
%- mo ^- (list ,[path ~])
|
||||
@ -2046,7 +2003,7 @@
|
||||
|- ^+ +.$
|
||||
?+ gem.dat ~| [%merge-weird-gem gem.dat] !!
|
||||
?(%mate %meld)
|
||||
=- %_(+.$ tag [- tag], wat.dat %merge)
|
||||
%- emit(wat.dat %merge)
|
||||
:* hen %pass
|
||||
[%merge (scot %p p.bob) q.bob (scot %p p.ali) q.ali %merge ~]
|
||||
%f %exec p.bob ~ [p.bob q.bob da/now] %tabl
|
||||
@ -2080,7 +2037,7 @@
|
||||
::
|
||||
++ build
|
||||
^+ .
|
||||
=- %_(+ tag [- tag], wat.dat %build)
|
||||
%- emit(wat.dat %build)
|
||||
:* hen %pass
|
||||
[%merge (scot %p p.bob) q.bob (scot %p p.ali) q.ali %build ~]
|
||||
%f %exec p.bob ~ [p.bob q.bob da/now] %tabl
|
||||
@ -2119,7 +2076,7 @@
|
||||
%- ~(urn by con)
|
||||
|= [pax=path *]
|
||||
(~(got by q.bas.dat) pax)
|
||||
=. con :: add/del conflict
|
||||
=. con :: change/del conflict
|
||||
%- ~(uni by con)
|
||||
%- mo ^- (list ,[path *])
|
||||
%+ skim (~(tap by old.dal.dat))
|
||||
@ -2128,7 +2085,7 @@
|
||||
~| %strange-add-and-del
|
||||
!!
|
||||
(~(has by can.dob.dat) pax)
|
||||
=. con :: add/del conflict
|
||||
=. con :: change/del conflict
|
||||
%- ~(uni by con)
|
||||
%- mo ^- (list ,[path *])
|
||||
%+ skim (~(tap by old.dob.dat))
|
||||
@ -2175,6 +2132,13 @@
|
||||
[(lobe-to-mark u.-) u.-]
|
||||
[p q.q]:cay
|
||||
[(~(put by hat) pax p.bol) (~(put by lat) p.bol bol)]
|
||||
:: ~& old=(~(run by old) mug)
|
||||
:: ~& newdal=(~(run by new.dal.dat) mug)
|
||||
:: ~& newdob=(~(run by new.dob.dat) mug)
|
||||
:: ~& caldal=(~(run by cal.dal.dat) mug)
|
||||
:: ~& caldob=(~(run by cal.dob.dat) mug)
|
||||
:: ~& hot=(~(run by hot) mug)
|
||||
:: ~& cas=(~(run by cas) mug)
|
||||
=+ ^- hat=(map path lobe) :: all the content
|
||||
%- ~(uni by old)
|
||||
%- ~(uni by new.dal.dat)
|
||||
@ -2183,6 +2147,7 @@
|
||||
%- ~(uni by cal.dob.dat)
|
||||
%- ~(uni by hot)
|
||||
cas
|
||||
:: ~& > hat=(~(run by hat) mug)
|
||||
=+ ^- del=(map path ,?)
|
||||
(~(run by (~(uni by old.dal.dat) old.dob.dat)) |=(~ %|))
|
||||
=. gon.dat [%& (sa (turn (~(tap by con)) head))]
|
||||
@ -2201,11 +2166,11 @@
|
||||
::
|
||||
++ checkout
|
||||
^+ .
|
||||
=- %_(+ tag [- tag], wat.dat %checkout)
|
||||
=+ ^- val=beak
|
||||
?: ?=(%init gem.dat)
|
||||
[p.ali q.ali cas.dat]
|
||||
[p.bob q.bob da/now]
|
||||
%- emit(wat.dat %checkout)
|
||||
:* hen %pass
|
||||
[%merge (scot %p p.bob) q.bob (scot %p p.ali) q.ali %checkout ~]
|
||||
%f %exec p.bob ~ val %tabl
|
||||
@ -2244,7 +2209,6 @@
|
||||
::
|
||||
++ ergo
|
||||
^+ .
|
||||
=- %_(+ tag [- tag], wat.dat %ergo)
|
||||
=+ ^- sum=(set path)
|
||||
=+ (must-ergo (turn (~(tap by erg.dat)) head))
|
||||
=+ (turn (~(tap by -)) (corl tail tail))
|
||||
@ -2256,6 +2220,7 @@
|
||||
?: ?=(%init gem.dat)
|
||||
[p.ali q.ali cas.dat]
|
||||
[p.bob q.bob da/now]
|
||||
%- emit(wat.dat %ergo)
|
||||
:* hen %pass
|
||||
[%merge (scot %p p.bob) q.bob (scot %p p.ali) q.ali %ergo ~]
|
||||
%f %exec p.bob ~ val %tabl
|
||||
@ -2292,17 +2257,15 @@
|
||||
(error:he %ergo-no-hez ~)
|
||||
?: ?=(%| -.gon.dat)
|
||||
+>.$
|
||||
%* done he
|
||||
reg
|
||||
=+ mus=(must-ergo (turn (~(tap by erg.dat)) head))
|
||||
%- welp :_ reg
|
||||
%+ turn (~(tap by mus))
|
||||
|= [pot=term len=@ud pak=(set path)]
|
||||
:* u.hez %ergo pot
|
||||
%+ turn (~(tap in pak))
|
||||
|= pax=path
|
||||
[(slag len pax) (~(got by can) pax)]
|
||||
==
|
||||
=+ mus=(must-ergo (turn (~(tap by erg.dat)) head))
|
||||
=< done:he
|
||||
%- emil
|
||||
%+ turn (~(tap by mus))
|
||||
|= [pot=term len=@ud pak=(set path)]
|
||||
:* u.hez %give %ergo pot
|
||||
%+ turn (~(tap in pak))
|
||||
|= pax=path
|
||||
[(slag len pax) (~(got by can) pax)]
|
||||
==
|
||||
::
|
||||
++ he
|
||||
@ -2350,7 +2313,6 @@
|
||||
=+ bol=(~(got by lat.ran) lob)
|
||||
?- -.bol
|
||||
%direct [%volt q.bol]
|
||||
%indirect [%volt q.bol]
|
||||
%delta [%pact $(lob q.q.bol) [%volt r.bol]]
|
||||
==
|
||||
::
|
||||
@ -2408,6 +2370,20 @@
|
||||
%boat
|
||||
:_ ..^$
|
||||
[hen %give %hill (turn (~(tap by mon.ruf)) head)]~
|
||||
::
|
||||
%drop
|
||||
=^ mos ruf
|
||||
=+ den=((de now hen ruf) [. .]:p.q.hic q.q.hic)
|
||||
abet:drop-me:den
|
||||
[mos ..^$]
|
||||
::
|
||||
%info
|
||||
?: =(%$ q.q.hic)
|
||||
[~ ..^$]
|
||||
=^ mos ruf
|
||||
=+ den=((de now hen ruf) [. .]:p.q.hic q.q.hic)
|
||||
abet:(exec:den now r.q.hic)
|
||||
[mos ..^$]
|
||||
::
|
||||
%init
|
||||
:_ %_ ..^$
|
||||
@ -2422,14 +2398,6 @@
|
||||
::
|
||||
~
|
||||
==
|
||||
::
|
||||
%info
|
||||
?: =(%$ q.q.hic)
|
||||
[~ ..^$]
|
||||
=^ mos ruf
|
||||
=+ den=((de now hen ruf) [. .]:p.q.hic q.q.hic)
|
||||
abet:(exec:den now r.q.hic)
|
||||
[mos ..^$]
|
||||
::
|
||||
%into
|
||||
=. hez.ruf `hen
|
||||
|
@ -216,6 +216,7 @@
|
||||
=. +> (sync %home our %base)
|
||||
=. +> ?. ?=(?(%king %czar) can) +>
|
||||
(sync %kids our %base)
|
||||
=. +> autoload
|
||||
=. +> peer
|
||||
|- ^+ +>+
|
||||
?~ myt +>+
|
||||
@ -255,7 +256,18 @@
|
||||
%_ +>.$
|
||||
moz
|
||||
:_ moz
|
||||
[hen %pass ~ %g %deal [our our] ram %poke %hood-sync -:!>(syn) syn]
|
||||
:* hen %pass /sync %g %deal [our our]
|
||||
ram %poke %hood-sync -:!>(syn) syn
|
||||
==
|
||||
==
|
||||
::
|
||||
++ autoload
|
||||
%_ .
|
||||
moz
|
||||
:_ moz
|
||||
:* hen %pass /autoload %g %deal [our our]
|
||||
ram %poke %kiln-start-autoload [%cube ~ [%atom %n]] ~
|
||||
==
|
||||
==
|
||||
::
|
||||
++ pump :: send diff ack
|
||||
|
@ -1122,6 +1122,7 @@
|
||||
%deal `%g
|
||||
%exec `%f
|
||||
%flog `%d
|
||||
%drop `%c
|
||||
%info `%c
|
||||
%merg `%c
|
||||
%mont `%c
|
||||
|
@ -1836,7 +1836,6 @@
|
||||
++ blob :: fs blob
|
||||
$% [%delta p=lobe q=[p=mark q=lobe] r=page] :: delta on q
|
||||
[%direct p=lobe q=page] :: immediate
|
||||
[%indirect p=lobe q=page r=lobe s=page] :: both
|
||||
== ::
|
||||
++ boat (map (pair bone wire) (trel bean ship path)) :: outgoing subs
|
||||
++ boon :: fort output
|
||||
@ -2360,6 +2359,7 @@
|
||||
== ::
|
||||
++ kiss-clay :: in request ->$
|
||||
$% [%boat ~] :: pier rebooted
|
||||
[%drop p=@p q=@tas] :: cancel pending merge
|
||||
[%info p=@p q=@tas r=nori] :: internal edit
|
||||
[%init p=@p] :: report install
|
||||
[%into p=@tas q=? r=mode] :: external edit
|
||||
|
13
gen/hood/autoload.hoon
Normal file
13
gen/hood/autoload.hoon
Normal file
@ -0,0 +1,13 @@
|
||||
::
|
||||
:::: /hoon/autoload/hood/gen
|
||||
::
|
||||
/? 314
|
||||
::
|
||||
::::
|
||||
!:
|
||||
:- %say
|
||||
|= $: [now=@da eny=@uvI bec=beak]
|
||||
[arg=?(~ [? ~]) ~]
|
||||
==
|
||||
:- %kiln-autoload
|
||||
`(unit ,?)`?~(arg ~ `-.arg)
|
@ -10,6 +10,7 @@
|
||||
++ kiln-pith ::
|
||||
$: rem=(map desk kiln-desk) ::
|
||||
syn=(map kiln-sync ,[let=@ud ust=bone]) ::
|
||||
autoload=? ::
|
||||
== ::
|
||||
++ kiln-desk :: per-desk state
|
||||
$: auto=? :: escalate on failure
|
||||
@ -54,6 +55,7 @@
|
||||
=> |% :: arvo structures
|
||||
++ card ::
|
||||
$% [%exec wire @p ~ [beak silk]] ::
|
||||
[%drop wire @p @tas] ::
|
||||
[%info wire @p @tas nori] ::
|
||||
[%mont wire @tas @p @tas path] ::
|
||||
[%ogre wire $|(@tas beam)] ::
|
||||
@ -64,6 +66,8 @@
|
||||
++ pear :: poke fruit
|
||||
$% [%talk-command command:talk] ::
|
||||
[%kiln-merge kiln-merge] ::
|
||||
[%helm-reload (list term)] ::
|
||||
[%helm-reset ~] ::
|
||||
== ::
|
||||
++ move (pair bone card) :: user-level move
|
||||
--
|
||||
@ -118,6 +122,10 @@
|
||||
|= kiln-merge
|
||||
abet:abet:(merge:(work syd) ali sud gim)
|
||||
::
|
||||
++ poke-cancel
|
||||
|= syd=desk
|
||||
abet:(emit %drop /cancel our syd)
|
||||
::
|
||||
++ do-info
|
||||
|= [mez=tape tor=toro]
|
||||
abet:(emit:(spam leaf/mez ~) %info /kiln our tor)
|
||||
@ -148,6 +156,25 @@
|
||||
=+ old=;;((map ,@da cord) (fall (file where) ~))
|
||||
(foal where %sched !>((~(put by old) tym eve)))
|
||||
::
|
||||
++ poke-autoload
|
||||
|= lod=(unit ,?)
|
||||
?^ lod
|
||||
abet(autoload u.lod)
|
||||
=< abet(autoload !autoload)
|
||||
(spam leaf/"turning autoload o{?:(autoload "ff" "n")}" ~)
|
||||
::
|
||||
++ poke-start-autoload
|
||||
|= ~
|
||||
=< abet
|
||||
%- emil
|
||||
%+ turn
|
||||
`(list term)`~[%ames %behn %clay %dill %eyre %ford %gall %zuse %hoon]
|
||||
|= syd=term
|
||||
^- card
|
||||
:* %warp /kiln/autoload/[syd] [our our] %home ~
|
||||
%next %y da/now /arvo/[syd]/hoon
|
||||
==
|
||||
::
|
||||
++ take |=(way=wire ?>(?=([@ ~] way) (work i.way))) :: general handler
|
||||
++ take-mere ::
|
||||
|= [way=wire are=(each (set path) (pair term tang))]
|
||||
@ -171,7 +198,7 @@
|
||||
==
|
||||
abet:abet:(mere:(auto hos) mes)
|
||||
::
|
||||
++ take-writ ::
|
||||
++ take-writ-sync ::
|
||||
|= [way=wire rot=riot]
|
||||
?> ?=([@ @ @ ~] way)
|
||||
=+ ^- hos=kiln-sync
|
||||
@ -181,6 +208,24 @@
|
||||
==
|
||||
abet:abet:(writ:(auto hos) rot)
|
||||
::
|
||||
++ take-writ-autoload
|
||||
|= [way=wire rot=riot]
|
||||
?> ?=([@ ~] way)
|
||||
?> ?=(^ rot)
|
||||
=+ syd=(slav %tas i.way)
|
||||
=. +>.$
|
||||
?. autoload
|
||||
+>.$
|
||||
?: ?=(%hoon syd)
|
||||
(emit %poke /kiln/reload/[syd] [our %hood] %helm-reset ~)
|
||||
(emit %poke /kiln/reload/[syd] [our %hood] %helm-reload ~[syd])
|
||||
=. +>.$
|
||||
%- emit :*
|
||||
%warp /kiln/autoload/[syd] [our our] %home ~
|
||||
%next %y da/now /arvo/[syd]/hoon
|
||||
==
|
||||
abet
|
||||
::
|
||||
++ spam
|
||||
|= mes=(list tank)
|
||||
((slog mes) ..spam)
|
||||
@ -244,7 +289,7 @@
|
||||
?+ p.p.mes
|
||||
:* (render "sync failed" sud her syd)
|
||||
leaf/"please manually merge the desks with"
|
||||
leaf/":+merge %{(trip syd)} {(scow %p her)} %{(trip sud)}"
|
||||
leaf/"|merge %{(trip syd)} {(scow %p her)} %{(trip sud)}"
|
||||
leaf/""
|
||||
leaf/"error code: {<p.p.mes>}"
|
||||
q.p.mes
|
||||
@ -457,7 +502,7 @@
|
||||
"""
|
||||
done setting up scratch space in {<[-]>}
|
||||
please resolve the following conflicts and run
|
||||
:+merge {<syd>} our {<[-]>}
|
||||
|merge {<syd>} our {<[-]>}
|
||||
"""
|
||||
%^ tanks-if-any
|
||||
"annotated conflicts in:" annotated
|
||||
|
415
pub/doc/arvo/clay/architecture.md
Normal file
415
pub/doc/arvo/clay/architecture.md
Normal file
@ -0,0 +1,415 @@
|
||||
# clay
|
||||
|
||||
## high-level
|
||||
|
||||
clay is the primary filesystem for the arvo operating system,
|
||||
which is the core of an urbit. The architecture of clay is
|
||||
intrinsically connected with arvo, but we assume no knowledge of
|
||||
either arvo or urbit. We will point out only those features of
|
||||
arvo that are necessary for an understanding of clay, and we will
|
||||
do so only when they arise.
|
||||
|
||||
The first relevant feature of arvo is that it is a deterministic
|
||||
system where input and output are defined as a series of events
|
||||
and effects. The state of arvo is simply a function of its event
|
||||
log. None of the effects from an event are emitted until the
|
||||
event is entered in the log and persisted, either to disk or
|
||||
another trusted source of persistence, such as a Kafka cluster.
|
||||
Consequently, arvo is a single-level store: everything in its
|
||||
state is persistent.
|
||||
|
||||
In a more traditional OS, everything in RAM can be erased at any
|
||||
time by power failure, and is always erased on reboot. Thus, a
|
||||
primary purpose of a filesystem is to ensure files persist across
|
||||
power failures and reboots. In arvo, both power failures and
|
||||
reboots are special cases of suspending computation, which is
|
||||
done safely since our event log is already persistent. Therefore,
|
||||
clay is not needed in arvo for persistence. Why, then, do we have a
|
||||
filesystem? There are two answers to this question.
|
||||
|
||||
First, clay provides a filesystem tree, which is a convenient
|
||||
user interface for some applications. Unix has the useful concept
|
||||
of virtual filesystems, which are used for everything from direct
|
||||
access to devices, to random number generators, to the /proc
|
||||
tree. It is easy and intuitive to read from and write to a
|
||||
filesystem tree.
|
||||
|
||||
Second, clay has a distributed revision control system baked into
|
||||
it. Traditional filesystems are not revision controlled, so
|
||||
userspace software -- such as git -- is written on top of them to
|
||||
do so. clay natively provides the same functionality as modern
|
||||
DVCSes, and more.
|
||||
|
||||
clay has two other unique properties that we'll cover later on:
|
||||
it supports typed data and is referentially transparent.
|
||||
|
||||
### Revision Control
|
||||
|
||||
Every urbit has one or more "desks", which are independently
|
||||
revision-controlled branches. Each desk contains its own mark
|
||||
definitions, apps, doc, and so forth.
|
||||
|
||||
Traditionally, an urbit has at least a base and a home desk. The
|
||||
base desk has all the system software from the distribution. the
|
||||
home desk is a fork of base with all the stuff specific to the
|
||||
user of the urbit.
|
||||
|
||||
A desk is a series of numbered commits, the most recent of which
|
||||
represents the current state of the desk. A commit is composed of
|
||||
(1) an absolute time when it was created, (2) a list of zero or
|
||||
more parents, and (3) a map from paths to data.
|
||||
|
||||
Most commits have exactly one parent, but the initial commit on a
|
||||
desk may have zero parents, and merge commits have more than one
|
||||
parent.
|
||||
|
||||
The non-meta data is stored in the map of paths to data. It's
|
||||
worth noting that no constraints are put on this map, so, for
|
||||
example, both /a/b and /a/b/c could have data. This is impossible
|
||||
in a traditional Unix filesystem since it means that /a/b is both
|
||||
a file and a directory. Conventionally, the final element in the
|
||||
path is its mark -- much like a filename extension in Unix. Thus,
|
||||
/doc/readme.md in Unix is stored as /doc/readme/md in urbit.
|
||||
|
||||
The data is not stored directly in the map; rather, a hash of the
|
||||
data is stored, and we maintain a master blob store. Thus, if the
|
||||
same data is referred to in multiple commits (as, for example,
|
||||
when a file doesn't change between commits), only the hash is
|
||||
duplicated.
|
||||
|
||||
In the master blob store, we either store the data directly, or
|
||||
else we store a diff against another blob. The hash is dependent
|
||||
only on the data within and not on whether or not it's stored
|
||||
directly, so we may on occasion rearrange the contents of the
|
||||
blob store for performance reasons.
|
||||
|
||||
Recall that a desk is a series of numbered commits. Not every
|
||||
commit in a desk must be numbered. For example, if the base desk
|
||||
has had 50 commits since home was forked from it, then a merge
|
||||
from base to home will only add a single revision number to home,
|
||||
although the full commit history will be accessible by traversing
|
||||
the parentage of the individual commits.
|
||||
|
||||
We do guarantee that the first commit is numbered 1, commits are
|
||||
numbered consecutively after that (i.e. there are no "holes"),
|
||||
the topmost commit is always numbered, and every numbered commit
|
||||
is an ancestor of every later numbered commit.
|
||||
|
||||
There are three ways to refer to particular commits in the
|
||||
revision history. Firstly, one can use the revision number.
|
||||
Secondly, one can use any absolute time between the one numbered
|
||||
commit and the next (inclusive of the first, exclusive of the
|
||||
second). Thirdly, every desk has a map of labels to revision
|
||||
numbers. These labels may be used to refer to specific commits.
|
||||
|
||||
Additionally, clay is a global filesystem, so data on other urbit
|
||||
is easily accessible the same way as data on our local urbit. In
|
||||
general, the path to a particular revision of a desk is
|
||||
/~urbit-name/desk-name/revision. Thus, to get /try/readme/md
|
||||
from revision 5 of the home desk on ~sampel-sipnym, we refer to
|
||||
/~sampel-sipnym/home/5/try/readme/md. Clay's namespace is thus
|
||||
global and referentially transparent.
|
||||
|
||||
XXX reactivity here?
|
||||
|
||||
### A Typed Filesystem
|
||||
|
||||
Since clay is a general filesystem for storing data of arbitrary
|
||||
types, in order to revision control correctly it needs to be
|
||||
aware of types all the way through. Traditional revision control
|
||||
does an excellent job of handling source code, so for source code
|
||||
we act very similar to traditional revision control. The
|
||||
challenge is to handle other data similarly well.
|
||||
|
||||
For example, modern VCSs generally support "binary files", which
|
||||
are files for which the standard textual diffing, patching, and
|
||||
merging algorithms are not helpful. A "diff" of two binary files
|
||||
is just a pair of the files, "patching" this diff is just
|
||||
replacing the old file with the new one, and "merging"
|
||||
non-identical diffs is always a conflict, which can't even be
|
||||
helpfully annotated. Without knowing anything about the structure
|
||||
of a blob of data, this is the best we can do.
|
||||
|
||||
Often, though, "binary" files have some internal structure, and
|
||||
it is possible to create diff, patch, and merge algorithms that
|
||||
take advantage of this structure. An image may be the result of a
|
||||
base image with some set of operations applied. With algorithms
|
||||
aware of this set of operations, not only can revision control
|
||||
software save space by not having to save every revision of the
|
||||
image individually, these transformations can be made on parallel
|
||||
branches and merged at will.
|
||||
|
||||
Suppose Alice is tasked with touching up a picture, improving the
|
||||
color balance, adjusting the contrast, and so forth, while Bob
|
||||
has the job of cropping the picture to fit where it's needed and
|
||||
adding textual overlay. Without type-aware revision control,
|
||||
these changes must be made serially, requiring Alice and Bob to
|
||||
explicitly coordinate their efforts. With type-aware revision
|
||||
control, these operations may be performed in parallel, and then
|
||||
the two changesets can be merged programmatically.
|
||||
|
||||
Of course, even some kinds of text files may be better served by
|
||||
diff, patch, and merge algorithms aware of the structure of the
|
||||
files. Consider a file containing a pretty-printed JSON object.
|
||||
Small changes in the JSON object may result in rather significant
|
||||
changes in how the object is pretty-printed (for example, by
|
||||
addding an indentation level, splitting a single line into
|
||||
multiple lines).
|
||||
|
||||
A text file wrapped at 80 columns also reacts suboptimally with
|
||||
unadorned Hunt-McIlroy diffs. A single word inserted in a
|
||||
paragraph may push the final word or two of the line onto the
|
||||
next line, and the entire rest of the paragraph may be flagged as
|
||||
a change. Two diffs consisting of a single added word to
|
||||
different sentences may be flagged as a conflict. In general,
|
||||
prose should be diffed by sentence, not by line.
|
||||
|
||||
As far as the author is aware, clay is the first generalized,
|
||||
type-aware revision control system. We'll go into the workings
|
||||
of this system in some detail.
|
||||
|
||||
### Marks
|
||||
|
||||
Central to a typed filesystem is the idea of types. In clay, we
|
||||
call these "marks". A mark is a file that defines a type,
|
||||
conversion routines to and from the mark, and diff, patch, and
|
||||
merge routines.
|
||||
|
||||
For example, a `%txt` mark may be a list of lines of text, and it
|
||||
may include conversions to `%mime` to allow it to be serialized
|
||||
and sent to a browswer or to the unix filesystem. It will also
|
||||
include Hunt-McIlroy diff, patch, and merge algorithms.
|
||||
|
||||
A `%json` mark would be defined as a json object in the code, and
|
||||
it would have a parser to convert from `%txt` and a printer to
|
||||
convert back to `%txt`. The diff, patch, and merge algorithms are
|
||||
fairly straightforward for json, though they're very different
|
||||
from the text ones.
|
||||
|
||||
More formally, a mark is a core with three arms, `++grab`,
|
||||
`++grow`, and `++grad`. In `++grab` is a series of functions to
|
||||
convert from other marks to the given mark. In `++grow` is a
|
||||
series of functions to convert from the given mark to other
|
||||
marks. In `++grad` is `++diff`, `++pact`, `++join`, and `++mash`.
|
||||
|
||||
The types are as follows, in an informal pseudocode:
|
||||
|
||||
++ grab:
|
||||
++ mime: <mime> -> <mark-type>
|
||||
++ txt: <txt> -> <mark-type>
|
||||
...
|
||||
++ grow:
|
||||
++ mime: <mark-type> -> <mime>
|
||||
++ txt: <mark-type> -> <txt>
|
||||
...
|
||||
++ grad
|
||||
++ diff: (<mark-type>, <mark-type>) -> <diff-type>
|
||||
++ pact: (<mark-type>, <diff-type>) -> <mark-type>
|
||||
++ join: (<diff-type>, <diff-type>) -> <diff-type> or NULL
|
||||
++ mash: (<diff-type>, <diff-type>) -> <diff-type>
|
||||
|
||||
These types are basically what you would expect. Not every mark
|
||||
has each of these functions defined -- all of them are optional
|
||||
in the general case.
|
||||
|
||||
In general, for a particular mark, the `++grab` and `++grow` entries
|
||||
(if they exist) should be inverses of each other.
|
||||
|
||||
In `++grad`, `++diff` takes two instances of a mark and produces
|
||||
a diff of them. `++pact` takes an instance of a mark and patches
|
||||
it with the given diff. `++join` takes two diffs and attempts to
|
||||
merge them into a single diff. If there are conflicts, it
|
||||
produces null. `++mash` takes two diffs and forces a merge,
|
||||
annotating any conflicts.
|
||||
|
||||
In general, if `++diff` called with A and B produces diff D, then
|
||||
`++pact` called with A and D should produce B. Also, if `++join`
|
||||
of two diffs does not produce null, then `++mash` of the same
|
||||
diffs should produce the same result.
|
||||
|
||||
Alternately, instead of `++diff`, `++pact`, `++join`, and
|
||||
`++mash`, a mark can provide the same functionality by defining
|
||||
`++sted` to be the name of another mark to which we wish to
|
||||
delegate the revision control responsibilities. Then, before
|
||||
running any of those functions, clay will convert to the other
|
||||
mark, and convert back afterward. For example, the `%hoon` mark
|
||||
is revision-controlled in the same way as `%txt`, so its `++grad`
|
||||
is simply `++sted %txt`. Of course, `++txt` must be defined in
|
||||
`++grow` and `++grab` as well.
|
||||
|
||||
Every file in clay has a mark, and that mark must have a
|
||||
fully-functioning `++grad`. Marks are used for more than just
|
||||
clay, and other marks don't need a `++grad`, but if a piece of
|
||||
data is to be saved to clay, we must know how to revision-control
|
||||
it.
|
||||
|
||||
Additionally, if a file is to be synced out to unix, then it must
|
||||
have conversion routines to and from the `%mime` mark.
|
||||
|
||||
##Using clay
|
||||
|
||||
### Reading and Subscribing
|
||||
|
||||
When reading from Clay, there are three types of requests. A
|
||||
`%sing` request asks for data at single revsion. A `%next`
|
||||
request asks to be notified the next time there's a change to
|
||||
given file. A `%many` request asks to be notified on every
|
||||
change in a desk for a range of changes.
|
||||
|
||||
For `%sing` and `%next`, there are generally three things to be
|
||||
queried. A `%u` request simply checks for the existence of a
|
||||
file at a path. A `%x` request gets the data in the file at a
|
||||
path. A `%y` request gets a hash of the data in the file at the
|
||||
path combined with all its children and their data. Thus, `%y`
|
||||
of a node changes if it or any of its children change.
|
||||
|
||||
A `%sing` request is fulfilled immediately if possible. If the
|
||||
requested revision is in the future, or is on another ship for
|
||||
which we don't have the result cached, we don't respond
|
||||
immediately. If the requested revision is in the future, we wait
|
||||
until the revision happens before we respond to the request. If
|
||||
the request is for data on another ship, we pass on the request
|
||||
to the other ship. In general, Clay subscriptions, like most
|
||||
things in Urbit, aren't guaranteed to return immediately.
|
||||
They'll return when they can, and they'll do so in a
|
||||
referentially transparent manner.
|
||||
|
||||
A `%next` request checks query at the given revision, and it
|
||||
produces the result of the query the next time it changes, along
|
||||
with the revsion number when it changes. Thus, a `%next` of a
|
||||
`%u` is triggered when a file is added or deleted, a `%next of a
|
||||
`%x` is triggered when a file is added, deleted, or changed, and
|
||||
a `%next` of a `%y` is triggered when a file or any of its
|
||||
children is added, deleted, or changed.
|
||||
|
||||
A `%many` request is triggered every time the given desk has a
|
||||
new revision. Unlike a `%next`, a `%many` has both a start and
|
||||
an end revsion, after which it stops returning. For `%next`, a
|
||||
single change is reported, and if the caller wishes to hear of
|
||||
the next change, it must resubscribe. For `%many`, every revsion
|
||||
from the start to the end triggers a response. Since a `%many`
|
||||
request doesn't ask for any particular data, there aren't `%u`,
|
||||
`%x`, and `%y` versions for it.
|
||||
|
||||
### Unix sync
|
||||
|
||||
One of the primary functions of clay is as a convenient user
|
||||
interface. While tools exist to use clay from within urbit, it's
|
||||
often useful to be able to treat clay like any other filesystem
|
||||
from the Unix perspective -- to "mount" it, as it were.
|
||||
|
||||
From urbit, you can run `|mount /path/to/directory %mount-point`,
|
||||
and this will mount the given clay directory to the mount-point
|
||||
directory in Unix. Every file is converted to `%mime` before it's
|
||||
written to Unix, and converted back when read from Unix. The
|
||||
entire directory is watched (a la Dropbox), and every change is
|
||||
auto-committed to clay.
|
||||
|
||||
### Merging
|
||||
|
||||
Merging is a fundamental operation for a distributed revision
|
||||
control system. At their root, clay's merges are similar to
|
||||
git's, but with some additions to accomodate typed data. There
|
||||
are seven different merge strategies.
|
||||
|
||||
Throughout our discussion, we'll say that the merge is from
|
||||
Alice's desk to Bob's. Recall that a commit is a date (for all
|
||||
new commits this will be the current date), a list of parents,
|
||||
and the data itself.
|
||||
|
||||
A `%init` merge should be used iff it's the first commit to a
|
||||
desk. The head of Alice's desk is used as the number 1 commit to
|
||||
Bob's desk. Obviously, the ancestry remains intact through
|
||||
traversing the parentage of the commit even though previous
|
||||
commits are not numbered for Bob's desk.
|
||||
|
||||
A `%this` merge means to keep what's in Bob's desk, but join the
|
||||
ancestry. Thus, the new commit has the head of each desk as
|
||||
parents, but the data is exactly what's in Bob's desk. For those
|
||||
following along in git, this is the 'ours' merge strategy, not
|
||||
the '--ours' option to the 'recursive' merge strategy. In other
|
||||
words, even if Alice makes a change that does not conflict with
|
||||
Bob, we throw it away. It's Bob's way or the highway.
|
||||
|
||||
A `%that` merge means to take what's in Alice's desk, but join
|
||||
the ancestry. This is the reverse of `%this`.
|
||||
|
||||
A `%fine` merge is a "fast-forward" merge. This succeeds iff one
|
||||
head is in the ancestry of the other. In this case, we use the
|
||||
descendant as our new head.
|
||||
|
||||
For `%meet`, `%mate`, and `%meld` merges, we first find the most
|
||||
recent common ancestor to use as our merge base. If we have no
|
||||
common ancestors, then we fail. If we have more than one most
|
||||
recent common ancestor, then we have a criss-cross situation,
|
||||
which should be handled delicately. At present, we delicately
|
||||
throw up our hands and give up, but something akin to git's
|
||||
'recursive' strategy should be implemented in the future.
|
||||
|
||||
There's a functional inclusion ordering on `%fine`, `%meet`,
|
||||
`%mate`, and `%meld` such that if an earlier strategy would have
|
||||
succeeded, then every later strategy will produce the same
|
||||
result. Put another way, every earlier strategy is the same as
|
||||
every later strategy except with a restricted domain.
|
||||
|
||||
A `%meet` merge only succeeds if the changes from the merge base
|
||||
to Alice's head (hereafter, "Alice's changes") are in different
|
||||
files than Bob's changes. In this case, the parents are both
|
||||
Alice's and Bob's heads, and the data is the merge base plus
|
||||
Alice's changed files plus Bob's changed files.
|
||||
|
||||
A `%mate` merge attempts to merge changes to the same file when
|
||||
both Alice and bob change it. If the merge is clean, we use it;
|
||||
otherwise, we fail. A merge between different types of changes --
|
||||
for example, deleting a file vs changing it -- is always a
|
||||
conflict. If we succeed, the parents are both Alice's and Bob's
|
||||
heads, and the data is the merge base plus Alice's changed files
|
||||
plus Bob's changed files plus the merged files.
|
||||
|
||||
A `%meld` merge will succeed even if there are conflicts. If
|
||||
there are conflicts in a file, then we use the merge base's
|
||||
version of that file, and we produce a set of files with
|
||||
conflicts. The parents are both Alice's and Bob's heads, and the
|
||||
data is the merge base plus Alice's changed files plus Bob's
|
||||
changed files plus the successfully merged files plus the merge
|
||||
base's version of the conflicting files.
|
||||
|
||||
That's the extent of the merge options in clay proper. In
|
||||
userspace there's a final option `%auto`, which is the most
|
||||
common. `%auto` checks to see if Bob's desk exists, and if it
|
||||
doesn't we use a `%init` merge. Otherwise, we progressively try
|
||||
`%fine`, `%meet`, and `%mate` until one succeeds.
|
||||
|
||||
If none succeed, we merge Bob's desk into a scratch desk. Then,
|
||||
we merge Alice's desk into the scratch desk with the `%meld`
|
||||
option to force the merge. For each file in the produced set of
|
||||
conflicting files, we call the `++mash` function for the
|
||||
appropriate mark, which annotates the conflicts if we know how.
|
||||
|
||||
Finally, we display a message to the user informing them of the
|
||||
scratch desk's existence, which files have annotated conflicts,
|
||||
and which files have unannotated conflicts. When the user has
|
||||
resolved the conflicts, they can merge the scratch desk back into
|
||||
Bob's desk. This will be a `%fine` merge since Bob's head is in
|
||||
the ancestry of the scratch desk.
|
||||
|
||||
### Autosync
|
||||
|
||||
Tracking and staying in sync with another desk is another
|
||||
fundamental operation. We call this "autosync". This doesn't mean
|
||||
simply mirroring a desk, since that wouldn't allow local changes.
|
||||
We simply want to apply changes as they are made upstream, as
|
||||
long as there are no conflicts with local changes.
|
||||
|
||||
This is implemented by watching the other desk, and, when it has
|
||||
changes, merging these changes into our desk with the usual merge
|
||||
strategies.
|
||||
|
||||
Note that it's quite reasonable for two desks to be autosynced to
|
||||
each other. This results in any change on one desk being mirrored
|
||||
to the other and vice versa.
|
||||
|
||||
Additionally, it's fine to set up an autosync even if one desk,
|
||||
the other desk, or both desks do not exist. The sync will be
|
||||
activated when the upstream desk comes into existence and will
|
||||
create the downstream desk if needed.
|
Loading…
Reference in New Issue
Block a user