# Darcs - easy VCS alternative to CVS

## charlieg

UPDATE: updated tutorial to use Darcs 0.9.20 commands which differ slightly from previous versions

UPDATE: added a few more descriptions in the "And Much More..." section

UPDATE: added a "Tips and Tricks" section

Introduction to Darcs

This is a brief introduction to Darcs - a distributed SCM [1] system and a healthy alternative to CVS.  It will show you an easy, more modern approach to VCS [2].  The project I contribute to (formerly XWT, renamed to Vexi) has greatly benefitted from moving to Darcs from CVS because now we can make rapid progress without the fear of making bad commits to the server or the server being down.  People can code and pull other's code at their own convenience.

[1] Source Control, Source Configuration Management, or Software Configuration Management depending on your perspective

[2] Version Control Systems

To achieve it's distributed goals, darcs doesn't remember a repository as a set of files but rather a set of patches.  The files are then created by applying the patches in chronological order.  This has multiple advantages, not least that of being selective in which patches you'd like to apply and thus being able to keep your repository in a modified state from that which other people might be using.

Some more advantages of darcs:It's distributed; no server to depend upon and little need to play with user access

It's simple to use; no server to set up and administer

It uses simple standards; easy to host your own public archives and easy to tinker with

Webserver hosting; simple to have your own multiple public repositories (although you don't have to - see the notes on the push command at the end of this tutorial)People might be slightly put off by the fact darcs is written in Haskell.  Don't be - this is the *nix world; right tool for the right job.  This is a very good application of Haskell.

Requirements and Prep

Tutorial requirements:A working Gentoo installation  :Wink: 

Your own web space, ideally with ssh access (must have 'authorized_keys' properly setup for passwordless access) and darcs installed

(but acceptable without - just follow ftp instructions instead)To install darcs is easy with Gentoo:

```
# emerge darcs
```

Creating Archives/Repositories

Next step is to set up your own working archive for your project, which is also really easy:

```
charlie # mkdir darcs/myproject

charlie # cd darcs/myproject

myproject # darcs initialize

Successfully initialized tree!
```

That was it.  That's how simple it is to create a repository.  :Wink: 

Adding files is also really easy:

```
myproject # echo "This is a test file" > testfile.txt

myproject # darcs add testfile.txt
```

To create patches, we use 'darcs record':

```
myproject # darcs record

Darcs needs to know what name (conventionally an email

address) to use as the author).  If you provide one now

I will store it in the file '_darcs/prefs/author', and

use it by default in the future.  To change your preferred

author address, simply delete this file.

 

What is your email address? charlie@vexi.org

addfile ./testfile.txt

Shall I record this patch? [ynWsfqdjk?] y

hunk ./testfile.txt 1

+This is a test file

Shall I record this patch? [ynWsfqdjk?] y

What is the patch name? test patch

Do you want to add a long comment? [yn] n

There is no test.

Finished recording patch 'test patch'
```

You'll only get asked for your email address the first time.

Now we've created our initial patch and thus the beginnings of our project repository.  Next step is to make our project publicly available.

Making It Publicly Available Over SSH

If you have ssh access, this is really easy.  First ssh into your web host and create an archive to synchronise with.

```
# ssh vexi.org

charlie $ cd ~/public_html/darcs

darcs $ mkdir myproject

darcs $ cd myproject

myproject $ darcs initialize

Successfully initialized tree!

myproject $ logout

Connection to vexi.org closed.
```

Now that's done, it's a quick process to synchronise our local and remote archives:

```
myproject # darcs push charlie@vexi.org:/home/charlie/public_html/darcs/myproject

[test patch

charlie@vexi.org**20040215174423]

Shall I push this patch? [ynWvqdjk?] y

So far so good... the merge succeeded.

Finished applying...
```

And that's it, your project archive/repository is now publicly available.

Making It Publicly Available Using FTP

First create another local archive to publish too (what we want the public archive to be):

```
charlie # cd ~/darcs

darcs # mkdir myproject_public

darcs # cd myproject_public

myproject_public # darcs initialize

Successfully initialized tree!
```

Then create a destination directory on your webhost using your favourite ftp application.

Next step is to apply your initial patch to your to-be-public archive:

```
myproject_public # cd ~/darcs/myproject

myproject # darcs push ~/darcs/myproject_public

[test patch

charlie@vexi.org**20040215174423]

Shall I push this patch? [ynWvqdjk?] y

So far so good... the merge succeeded.

Finished applying...
```

Now use your favourite ftp application to copy everything over in your darcs/myproject_public folder over to your web host.  Et voila, you're sharing your project archive/repository.

Updating Your Public Archive

Now everything is in place, this is where it gets really easy.

First, let's make a change.  Edit testfile.txt to say something like:

```
This is now a modified test file!
```

To update it, it's a simple process.  First we record the patch:

```
myproject # darcs record

hunk ./testfile.txt 1

-This is a test file

+This is a modified test file!

Shall I record this patch? [ynWsfqdjk?] y

What is the patch name? update

Do you want to add a long comment? [yn] n

There is no test.

Finished recording patch 'update'
```

Darcs remembers the location of the last push and will use it as default.  So, now all we need to do is:

```
myproject # darcs push

Pushing to charlie@vexi.org:/home/charlie/public_html/darcs/myproject

[update

charlie@vexi.org**20040215183048]

Shall I push this patch? [ynWvqdjk?] y

So far so good... the merge succeeded.

Finished applying...
```

Note for ftp users:The pushing to desination will read "/home/charlie/darcs/myproject_public..."You have to remember to upload the updated archive from myproject_public to your destination folder on your web host

And Much More...

This introduction only touches the tip of the ability of darcs.  

Other things of note:

darcs push

You push patches to a repository.

If you try to push to a repo where you do not have direct access (eg a website - darcs push http://darcs.vexi.org/core) then darcs will handily default to emailing the patch to a chosen destination instead.  People can then use that email to apply the patch, which is useful if you do not wish to host a public repo.

darcs get

If you want to get somebody elses project archive, use darcs get:

```
# darcs get http://darcs.vexi.org/core
```

If the project archive you are dealing with has a lot of patches, usually the maintainer will have set checkpoints (ie at each new version) and you can get the latest checkpoint using darcs get --partial:

```
# darcs get --partial http://darcs.vexi.org/core
```

Also, if you want to get to be more verbose (useful when getting large archives) use the --verbose flag:

```
# darcs get --verbose http://darcs.vexi.org/core
```

darcs pull

Of course, you only want to get a repo once.  To get patches from other peoples repositories, use darcs pull:

```
# darcs pull http://darcs.vexi.org/core
```

darcs add

Use add to add files.  It can be made recursive:

```
darcs add -r dirname
```

It works with standard CLI syntax, eg to add all the contents of a particular directory:

```
darcs add dirname/*
```

darcs mv

You can seamlessly move files around using darcs mv - note that you can't just use the standard CLI 'mv' on it's own as darcs has know way of knowing which files have been moved where without being explicitly told.  Instead, if you just used 'mv' then darcs would treat it as a rm/add which would 1) lose your patch history on the file and 2) mean that patches created in another version of the codebase before the rm/add would no longer be appliable to your repo as the file they expect no longer exists.

So darcs mv is important to allow the moving of files whilst maintaining patch consistency.

darcs remove

To get rid of files just use darcs remove to drop files.  Even easier than that, you can just delete them (ie 'rm file') and Darcs will pick up on that for you.

what about modules and branches?

CVS introduced the concept of modules and branches into the SCM world.  Since darcs doesn't require a server, there is no real need for modules or branches.  You can just create new directories as needed (using darcs inittree) and use them as project holders.  You could just have the directories myproject_stable and myproject_head as darcs repositories and selectively apply patches to them.

learning more about darcs

Darcs is one of those strange open source projects that has really good documentation.  What are you waiting for?  Check it out!

Tips and Tricks

--help

The --help flag is always useful when memory isn't serving well.  Try darcs --help to get an overview of commands or darcs <command> --help to get help on a specific command.

-a

You can use the -a flag to imply all.  This can be handy when you have a lot of patches you want to unselectively push to or pull from a repo:

```
# darcs push -a charlie@vexi.org:/home/charlie/public_darcs/core

# darcs pull -a http://darcs.vexi.org/core 
```

whatsnew

Not sure about what you've been up to with your code?  Want to go over it before diving into darcs record?  Then darcs whatsnew will do it for you.

--look-for-adds

Ever the demon of any development repo is missing files - files you have created on your machine but forgotten to add to the repo.  Use darcs whatsnew --look-for-adds to track them down for you.

changes

Want to know what you've changed?  Use 'darcs changes' to get an overview of patches.

Getting specific information

In a large repo with 100s or 1000s of patches, the info from something like darcs changes can be too much.  But almost all darcs commands can be target specifically at any part of your repo.

For instance, if you want to know what patches have affected a particular file:

```
# darcs changes path/to/file
```

Example:

```
charlie@mightymax widgets $ darcs changes src/main.t

Changes to src/main.t:

Sat May  1 02:24:42 GMT 2004  charlie@vexi.org

  * add Vexi demo

Tue Apr 20 23:08:36 GMT 2004  tupshin@tupshin.com

  * changed ibex namespace to vexi and reoganized widgets to match

Tue Apr 20 20:55:20 GMT 2004  tupshin@tupshin.com

  * changing root tag to be vexi and not ibex

Tue Apr  6 01:02:08 GMT 2004  david@zentus.com

  * reorganise namespace

Tue Mar  2 16:01:43 GMT 2004  charlie@xwt.org

  * development snapshot of ibex widgets
```

Another handy example is if you have been working in a particular directory and want to check out what is new or record changes in the specific directory:

```
# darcs whatsnew path/to/dir

# darcs record path/to/dir
```

Example:

```
charlie@mightymax widget $ pwd

/home/charlie/darcs/org/vexi/widgets/src/vexi/widget

charlie@mightymax widget $ darcs whatsnew .

What's new in "src/vexi/widget":

{

hunk ./src/vexi/widget/list.t 32

-        redirectTo($widget, "enabled", "fill", "numselected", "text", "value", "values", "setValue", "setValues");

+        redirectTo($widget, "enabled", "fill", "numselected", "text", "selected", "value", "values", "setValue", "setValues");

}

charlie@mightymax widget $ darcs record .

Recording changes in "src/vexi/widget":

hunk ./src/vexi/widget/list.t 32

-        redirectTo($widget, "enabled", "fill", "numselected", "text", "value", "values", "setValue", "setValues");

+        redirectTo($widget, "enabled", "fill", "numselected", "text", "selected", "value", "values", "setValue", "setValues");

Shall I record this patch? [ynWsfqdjk?] y

What is the patch name? Can cancel this with Ctrl-C...Interrupted!
```

----------

## charlieg

Some examples might be nice, eh?  :Wink: 

A few of my darcs code repositories can be found here:

www.charlietech.com/darcs

----------

## S_aIN_t

looks very nice.. might give it a try.. thanks for top-notch work. :)

----------

## charlieg

 *S_aIN_t wrote:*   

> looks very nice.. might give it a try.. thanks for top-notch work. 

 

It is very nice, do give it a try, and you're welcome.  :Wink: 

----------

## axxackall

Any chance to compile it on Hugs98? GHC is not ported to Linux/PPC. Depending Darcs on GHC doesn't make it a cross platform.   :Sad: 

----------

## charlieg

 *axxackall wrote:*   

> Any chance to compile it on Hugs98? GHC is not ported to Linux/PPC. Depending Darcs on GHC doesn't make it a cross platform.  

 

That's a question to ask to the darcs user mailing list.  I couldn't even begin to answer it.

----------

## ebrostig

Does it work behind HTTP based proxies?

CVS does not and that stops me from using any ebuild that requires DVS access. BitKeeper works fine through our firewall. How does this puppy stack up?

Erik

----------

## charlieg

 *ebrostig wrote:*   

> Does it work behind HTTP based proxies?
> 
> CVS does not and that stops me from using any ebuild that requires DVS access. BitKeeper works fine through our firewall. How does this puppy stack up?

 

I cannot see why it wouldn't work behind an http proxy.  It does all serving over http.

As for updating, it works behind anything you can ssh to or ftp to, depending on how you're updating.

----------

## charlieg

Btw, please post if this has lead you to trying and liking Darcs as an alternative to CVS (or any other VCS).

----------

## gour

Hi!

 *charlieg wrote:*   

> Btw, please post if this has lead you to trying and liking Darcs as an alternative to CVS (or any other VCS).

 

I already know for darcs for quite some time (compiling it even on win98 under win4lin under msys environment), but still I'd liek to thank you to put your howto together.

darcs is really a greatr piece of software, VERY easy to setup & use and the author is ready to hear feedback.

I'm just sorry for not having darcs installed on my web-hosted server so I'd be able to push my patches on the web server. (at least, there is rsync -update solution  :Smile: 

Sincerely,

Gour

----------

## charlieg

 *gour wrote:*   

> I'm just sorry for not having darcs installed on my web-hosted server so I'd be able to push my patches on the web server. (at least, there is rsync -update solution 

 

There are a couple of ways to get around this.

[EDIT - I'm wrong with the first point here (darcs must be on the webserver) and Gour already uses the second method]

 :Arrow:  Create an empty directory locally, 'darcs inittree', then upload that to your webhost.  You should then be able to 'push --and-apply' to that directory on your web host (darcs is not required to be on the webserver in order to do this, but you must have ssh access).

 :Arrow:  Create a 'sync dir' locally that you 'push --and-apply' to, and the rsync / ftp that directory to your web host.  I described this in more detail in the original post.

----------

## gour

 *Quote:*   

> 
> 
>  Create an empty directory locally, 'darcs inittree', the upload that to your webhost.  You should then be able to 'push --and-apply' to that directory on your web host (darcs is not required to be on the webserver in order to do this, but you must have ssh access).
> 
>  Create a 'sync dir' locally that you 'push --and-apply' to, and the rsync / ftp that directory to your web host.  I described this in more detail in the original post.

 

Hmmm... I saved your original post but thought it's only scenario when having darcs installed on the server   :Sad: 

I even mentioned that on darcs' mailing list, and David confirmed that's is not easy to get web-hosted server with ghc on it    :Very Happy: 

This is a real enlightenment  :Laughing: 

Thanks a lot. I'm going to try it (fortunately I have ssh  :Wink: 

Sincerely,

Gour

----------

## gour

 *Quote:*   

>  Create a 'sync dir' locally that you 'push --and-apply' to, and the rsync / ftp that directory to your web host.  I described this in more detail in the original post.

 

This approach is working here (with rsync), but I'd like to explore this one:

 *Quote:*   

> 
> 
>  Create an empty directory locally, 'darcs inittree', then upload that to your webhost.  You should then be able to 'push --and-apply' to that directory on your web host (darcs is not required to be on the webserver in order to do this, but you must have ssh access).

 

I created empty directory locally and uploaded it on my webhost.

Then locally I added a test file and recorded test patch.

But trying to push this onto my web host server gives me:

```
bash-2.05b$ darcs push --and-apply atmarama@atmarama.org:/home/atmarama/www/darcs/test

Wed Mar  3 17:40:48 CET 2004  atmarama@atmarama.org

  * test patch

Shall I push this patch? [ynWvqdjk?] y

jailshell: line 1: darcs: command not found
```

Am I missing something  :Question: 

Sincerely,

Gour

----------

## charlieg

 *gour wrote:*   

> I created empty directory locally and uploaded it on my webhost.
> 
> Then locally I added a test file and recorded test patch.
> 
> But trying to push this onto my web host server gives me:
> ...

 

No, I was... updating the howto accordingly.

----------

## charlieg

People who use darcs with large repos will not that it be a slow process to get a large set of patches and to apply them, and that patch emails have a long history list.

This is solved using a combination of optimize and checkpoint.  You should consult the official darcs documentation on how to use these.

----------

## Jeedo

I've never heard of this VCS before, how does it compare to stuff like subversion ( which i use ) or Arch ( since it's distributed also )

----------

## charlieg

 *Jeedo wrote:*   

> I've never heard of this VCS before, how does it compare to stuff like subversion ( which i use ) or Arch ( since it's distributed also )

 

It'd take a long time to do a thorough comparison.  In the darcs documentation there is a decent and relatively impartial overview of the differences between arch and darcs.

----------

## charlieg

If you're not using darcs 0.9.19, you should be.

EDIT: make that 0.9.20+!

----------

## dhurt

Thanks for the howto  :Very Happy: .  I had couple comments and questions.  I am not sure, but the following commands did not work for me:

```

myproject # darcs inittree 

```

Should be:

```

myproject # darcs initialize

```

And I could not get this flag working:

```

darcs push --and-apply charlie@xwt.org:/home/charlie/public_html/darcs/myproject

darcs failed:  unrecognized option `--and-apply'

```

Not sure but I did not see the --and-apply switch in the manual.  One final question, I could not figure out how to get daracs working with a different port than the default SSH port.  Where would I specify the enviornmental varialbes that they talk about in the manual like SSH_PORT, DARCS_SSH and DARCS_SCP?  Do you specifcy them in your _darcs/prefs/defaults file or do you specify them on the command line?

For instance I tried this command:

```

DARCS_SCP="scp -P 2024 " DARCS_SSH="ssh -p 2024 " SSH_PORT="2024 "  darcs push -a hurt@xenophobia:/var/www/localhost/htdocs/project

darcs failed:  (scp) failed to fetch: hurt@xenophobia:/var/www/localhost/htdocs/project/_darcs/inventory

```

and I could not connect.  I switched to the standard SSH port and it worked great.  So I must not be setting the port right.  I googled around and looked through the manual and could not find any information really.  If noone happenes to know the answer off hand, I will try and join their mailign list and I am sure they know the answer.

----------

## charlieg

Well noticed dhurt and glad to see people trying this how-to.

```
darcs inittree

darcs push --and-apply
```

These have been deprecated in 0.9.20 in favour of just:

```
darcs initialize

darcs push
```

I'm updating the original post to reflect this!

----------

## charlieg

 *dhurt wrote:*   

> Where would I specify the enviornmental varialbes that they talk about in the manual like SSH_PORT, DARCS_SSH and DARCS_SCP?  Do you specifcy them in your _darcs/prefs/defaults file or do you specify them on the command line?
> 
> For instance I tried this command:
> 
> ```
> ...

 

That looks more like a problem with the particular repo than SSH problems.

Does _darcs/inventory exist in the repo?  Did you remember to darcs initialize server-side?

----------

## nevynxxx

```

anferny root # emerge -av darcs

These are the packages that I would merge, in order:

Calculating dependencies

!!! all ebuilds that could satisfy "darcs" have been masked.

!!! possible candidates are:

- dev-util/darcs-0.9.19 (masked by: ~keyword)

- dev-util/darcs-0.9.20 (masked by: ~keyword)

- dev-util/darcs-0.9.17 (masked by: ~keyword)

!!! Error calculating dependencies. Please correct.

```

Grrr, guess I'm getting another unstable app on my server...ohh well.

----------

## charlieg

 *nevynxxx wrote:*   

> Grrr, guess I'm getting another unstable app on my server...ohh well.

 

Darcs is not 'unstable' by any stretch of the imagination.  Just it's not (yet) widely adopted so not many people will have tested it.

----------

## nevynxxx

 *charlieg wrote:*   

>  *nevynxxx wrote:*   Grrr, guess I'm getting another unstable app on my server...ohh well. 
> 
> Darcs is not 'unstable' by any stretch of the imagination.  Just it's not (yet) widely adopted so not many people will have tested it.

 

Ohh don't get me wrong, I know the diffrence between stable, and arched: Version numbers. Its just easier to keep track of versions when a computer is ~x86 or not, not a bit of both. So i like to keep my number of ~x86 packages down on the server.

I was more wondering why it's marked ~x86 in portage.

----------

## charlieg

 *nevynxxx wrote:*   

> I was more wondering why it's marked ~x86 in portage.

 

And you made me wonder too.  Just logged this:

https://bugs.gentoo.org/show_bug.cgi?id=53293

----------

## dhurt

Yes, I initialize the directory on both sides.  I think that the error is with the ssh port settings, because as soon as I switch the port to the default port it works correctly.

Oh well, I will just use the default port for now and mess with it latter.  Thanks again for the how-to.

If I already have a project going.  Do I just initialize in the directory and then add all the files in the directory?

----------

## charlieg

 *dhurt wrote:*   

> If I already have a project going.  Do I just initialize in the directory and then add all the files in the directory?

 

That's one way, but then you'll lose all the history of your previous SCM - is it CVS?

Ask on the darcs users mail list for information about how to convert your SCM archive to Darcs.

----------

## charlieg

 *charlieg wrote:*   

> Ask on the darcs users mail list for information about how to convert your SCM archive to Darcs.

 

Even better, consult the Darcs Wiki!  Just came across it:

http://www.scannedinavian.org/DarcsWiki/FrontPage

----------

## charlieg

Well darcs has long since gotten a better URL, www.darcs.net, gone gold with 1.0, and is now at 1.0.2 after months of testing / bug fixing.

It's pretty solid now (in my experience) and has a large and growing user community.

----------

## linux_girl

haskell cury realy rocks:P  :Razz: 

----------

## SerfurJ

how do you set up darcs webserver access on gentoo?  the documentation says to use a cgi script included with the package, but the gentoo package has no cgi script.

```
# equery f darcs                                                                                            [0]

[ Searching for packages matching darcs... ]

dev-util/darcs-1.0.2

* Contents of dev-util/darcs-1.0.2:

/etc

/etc/bash_completion.d

/etc/bash_completion.d/darcs

/usr

/usr/bin

/usr/bin/darcs

/usr/share

/usr/share/man

/usr/share/man/man1

/usr/share/man/man1/darcs.1.gz

```

----------

## charlieg

No idea, sorry.  I just use SSH for push access and only web access for getting/pulling patches.

----------

## SerfurJ

 *charlieg wrote:*   

> No idea, sorry.  I just use SSH for push access and only web access for getting/pulling patches.

 

so you must've set up darcs to work with your web server for that.  could you point me to the section of the documentation describing how to do that?  thanks.

----------

## gour

Hi!

 *SerfurJ wrote:*   

> so you must've set up darcs to work with your web server for that.  could you point me to the section of the documentation describing how to do that?  thanks.

 

```
make installserver
```

will do the job  :Wink: 

See GNUmakefile for the details.

Sincerely,

Gour

----------

## SerfurJ

 *gour wrote:*   

> 
> 
> ```
> make installserver
> ```
> ...

 

i saw that, but i wanted to use the ebuild that's in portage.  did you build darcs manually?

----------

## charlieg

 *SerfurJ wrote:*   

> so you must've set up darcs to work with your web server for that.

 

That's SSH that you need to set up.

If you already have it installed, you need to have your public key on the server and openssh on the server set up to allow passwordless logins.  I don't really know the specifics, sorry, as somebody else manages the servers I log into.

Darcs then seemlessly works over SSH, no changes needed, e.g.:

```
darcs push vexi.org:/home/charlie/darcs/org.vexi.core
```

----------

## SerfurJ

sorry, i wasn't specific enough.  i wanted to know how you set up web access for getting/pulling patches.

 *charlieg wrote:*   

> I just use ... and ... web access for getting/pulling patches.

 

----------

## gour

 *SerfurJ wrote:*   

> i saw that, but i wanted to use the ebuild that's in portage.  did you build darcs manually?

 

Well, I don't use server, but you can go in the 

```
/var/tmp/portage/darcs
```

direcotory and there execute: 

```
make installserver
```

Sincerely,

Gour

----------

## SerfurJ

thanks for all the help guys..

gour,

i have no

```
/var/tmp/portage/darcs
```

directory.  

is it possible that whoever made the darcs ebuild just didn't include darcs webserver support?  i expected to see something like an apache2 use flag for the darcs ebuild.

----------

## gour

 *SerfurJ wrote:*   

> gour,
> 
> i have no
> 
> ```
> ...

 

Sure. You have to create it, i.e.

```
ebuild /usr/portage/dev-util/darcs/darcs-1.0.3.ebuild unpack

ebuild /usr/portage/local/dev-util/darcs/darcs-1.0.3.ebuild compile

cd /var/tmp/portage/darcs-1.0.3/work/darcs-1.0.3/

make installserver
```

Take also look at man ebuild  :Cool: 

Sincerely,

Gour

----------

## SerfurJ

that worked!  thanks again.

----------

## SerfurJ

 *dhurt wrote:*   

> 
> 
> For instance I tried this command:
> 
> ```
> ...

 

i have the same problem.  nobody on #darcs had an answer, so i guess it's a bug.

----------

## dcoutts

 *axxackall wrote:*   

> Any chance to compile it on Hugs98? GHC is not ported to Linux/PPC. Depending Darcs on GHC doesn't make it a cross platform.  

 

darcs-1.0.5 is stable on ppc. It's ~sparc and ~amd64 too. We should be able to get it working on ppc64 and possibly alpha. Does anyone need any other arches?

----------

