Darcs – what, why and howurchin.earth.li/~ganesh/darcs-lhug-apr-13.pdf · 2015. 9. 26. · like...

Preview:

Citation preview

Darcs – what, why and how

Ganesh SittampalamLondon HUG, 24th April 2013

So what is it?

A distributed version control systemlike git, mercurial, etc

and unlike svn, cvs, etc

Based on patches as first-class objectsunlike git, mercurial, etc

Hasn’t git won?

If Darcs didn’t exist, it’d be worth writing now

A fundamentally different model

Hybrid future - bridges to git etc

First-class patches?

A philosophical differencelike Haskell versus C#

A practical differenceCherry-picking is cheap and reversible

Merges are deterministic

Darcs philosophy

A simple, intuitive user model

(we like to think)

A simple command set

Commands are interactive by default

What doesn’t darcs have?

Multi-head repos

Good conflict handling

Short revision identifiers

Github

Lots of tools

Lots of users

Extreme speed

Demo

Rebase

Coming in darcs 2.10

Much less necessary than in tree-based systemsNo need to tidy up history to remove merges

Conflict-free cherry-picking isn’t a rebase

Basic operations: “suspend”, “unsuspend”

Demo

Commands

Localinit

recordunrecord

amend-record

revertunrevert

rollback

tag

Queryingchanges

whatsnewdiff

annotate

Specific patch typesadd

moveremove

replace

Remotegetput

pullpush

obliterate(unpull)

sendapply

What is a darcs patch?

A description of how to change a tree

e.g. “remove text X starting at lines 3 and add text Y instead”

Add file A

Rename file B to C

Replace token X with token Y in file Z

Darcs patches are invertible

e.g. “remove X and add Y at line 3”

“remove Y and add X at line 3”

An important part of reversible cherry-picking

Darcs underapproximates dependencies, most systems overapproximate them

Deterministic merging

Merge algorithm part of patch type

No merge commitsMerges are reproducible

Merging is “associative”

Internally, the inverse of merging is commuting:

B

We write AB’ ↔ BA’

To cherry pick, commute unwanted patches to the end

A

B’

A’

final

initial

intermediate

?

A

B

B’

A’

?

base

Tree A

Tree B

A darcs repository is set of patches

Stored in an order - this shows up in the UI

Two repositories with the same patches but in different orders will be equivalent

Patches retain their identity in different contexts

But can change their representation

A bit more “theory”

No clear formalism

But there are some “laws” we believe are true

e.g.

AB ↔ B’A’

B’A’ ↔ AB

B’-1A ↔ A’B-1

“Permutivity”

A

BB’

A’

CC’

A’’

C’’

B’’

A’’’

B’’’

C’’’

“Permutivity”

A

BB’

A’

CC’

A’’

C’’

B’’

A’’’

B’’’

C’’’

ABC

“Permutivity”

A

BB’

A’

CC’

A’’ABC

B’A’C

C’’

B’’

A’’’

B’’’

C’’’

“Permutivity”

A

BB’

A’

CC’

A’’ABC

B’A’C

B’C’A’’

C’’

B’’

A’’’

B’’’

C’’’

“Permutivity”

A

BB’

A’

CC’

A’’ABC

B’A’C

B’C’A’’

C’’B’’A’’

C’’

B’’

A’’’

B’’’

C’’’

“Permutivity”

A

BB’

A’

CC’

A’’ABC

B’A’C

B’C’A’’

C’’B’’A’’

C’’A’’’B’’’

C’’

B’’

A’’’

B’’’

C’’’

“Permutivity”

A

BB’

A’

CC’

A’’ABC

B’A’C

B’C’A’’

C’’B’’A’’

C’’A’’’B’’’

A’’’’C’’’B’’’C’’

B’’

A’’’

B’’’

C’’’

“Permutivity”

A

BB’

A’

CC’

A’’ABC

B’A’C

B’C’A’’

C’’B’’A’’

C’’A’’’B’’’

A’’’’C’’’B’’’

A’’’’B’’’’C’’’’

C’’

B’’

A’’’

B’’’

C’’’

Patch “witnesses”

Patches need to be moved between contexts

Representation sometimes changes

Easy to get it wrong

data Patch = Null | Seq Patch Patch

commute :: (Patch, Patch)

Maybe (Patch, Patch)

commute (Seq a b, c) = do

(c’, a’) commute (a, c )

(c’’,b’) commute (b, c’)

return (c’’, Seq a’ b’)

(AB)C ?

data Patch a b where

Null :: Patch a a

Seq :: Patch a b Patch b c Patch a c

data PatchPair a b where

Pair :: Patch a b Patch b c PatchPair a c

commute :: PatchPair a cMaybe (PatchPair a c)

commute (Pair (Seq a b) c) = do

Pair c’ a’ commute (Pair a c)

Pair c’’ b’ commute (Pair b c’)

return (Pair c’’ (Seq a’ b’))

Bring in GADTs!

witnessed.hs:14:37:Couldn't match type `b' with `b1'`b' is a rigid type variable bound by

a pattern with constructorPair :: forall a c b. Patch a b -> Patch b c -> PatchPair a c,

in an equation for `commute'at witnessed.hs:13:10

`b1' is a rigid type variable bound bya pattern with constructorSeq :: forall a c b. Patch a b -> Patch b c -> Patch a c,

in an equation for `commute'at witnessed.hs:13:16

Expected type: Patch b1 cActual type: Patch b c

In the second argument of `Pair', namely `c'In the first argument of `commute', namely `(Pair a c)'In a stmt of a 'do' block: Pair c' a' <- commute (Pair a c)

What’s next?

Release 2.10: rebase, fast annotate

Finish and develop git bridge

Improve hosting

Graphical tools

Multi-head repos

Better conflict handling

Develop more patch types

More info

http://darcs.net

Hosting: http://hub.darcs.net

Participating in GSoC (via haskell.org)

- please apply!