Search posterous

Search all posts and users. Type a name, type a favorite song title, whatever! See what comes up.
  

More posterous blogs











More recommended blogs »

Here are posterous posts filed under mercurial...

hdknr says...

The Big Idea

The Hg-Git plugin can convert commits/changesets losslessly from one system to another, so you can push via a Mercurial repository and another Mercurial client can pull it and their changeset node ids will be identical - Mercurial data does not get lost in translation.

It is intended that Hg users may wish to use this to collaborate even if no Git users are involved in the project, as it may provide some advantages if you're using Bookmarks (it will transfer bookmarks on push, which Mercurial doesn't do).

Filed under: Mercurial

Filed under: mercurial

hdknr says...

今度はぐぐっても発見できない。って、素直に付属のドキュメント見ればいいやんけ、と自己突っ込みしながらdoc/hgrc.5.htmlを眺める。pushを許可するには以下の設定が必要らしい。

[web]
allow_push = *
via vmi.jp

Filed under: Mercurial

hdknr says...

http://hdknr.posterous.com/mercurial-install-on-a-virtualenv で Mercurialがvirtualenvにすんなりはいったので、
apacheで動かしてみる。

(hg)hdknr@deblen:~/.ve/hg$ mkdir repos
(hg)hdknr@deblen:~/.ve/hg$ ls -al
合計 28
drwxr-xr-x  7 hdknr hdknr 4096 2009-10-23 11:10 .
drwxr-xr-x 10 hdknr hdknr 4096 2009-10-23 11:00 ..
drwxr-xr-x  2 hdknr hdknr 4096 2009-10-23 11:05 bin
drwxr-xr-x  2 hdknr hdknr 4096 2009-10-23 11:00 include
drwxr-xr-x  3 hdknr hdknr 4096 2009-10-23 11:00 lib
drwxr-xr-x  2 hdknr hdknr 4096 2009-10-23 11:10 repos
drwxr-xr-x  3 hdknr hdknr 4096 2009-10-23 11:00 src

レポジトリ初期化。
(hg)hdknr@deblen:~/.ve/hg/repos$ hg init
(hg)hdknr@deblen:~/.ve/hg/repos$ date > readme.txt
(hg)hdknr@deblen:~/.ve/hg/repos$ hg status
? readme.txt
(hg)hdknr@deblen:~/.ve/hg/repos$ hg add readme.txt
(hg)hdknr@deblen:~/.ve/hg/repos$ hg status
A readme.txt
(hg)hdknr@deblen:~/.ve/hg/repos$ hg commit -u hdknr -m "hello"
(hg)hdknr@deblen:~/.ve/hg/repos$ hg status


設定ファイル作成。
(hg)hdknr@deblen:~/.ve/hg$ cat > hgweb.config
[collections]
repos/ = /home/hdknr/.ve/hg/repos/

WSGIスクリプト準備。
(hg)hdknr@deblen:~/.ve/hg$ find src/mercurial-stable/ -name "hgwebdir.*" -print
src/mercurial-stable/contrib/hgwebdir.fcgi
src/mercurial-stable/contrib/hgwebdir.wsgi
src/mercurial-stable/hgwebdir.cgi
src/mercurial-stable/.hg/store/data/contrib/hgwebdir.fcgi.i
src/mercurial-stable/.hg/store/data/contrib/hgwebdir.wsgi.i
src/mercurial-stable/.hg/store/data/hgwebdir.cgi.i

(hg)hdknr@deblen:~/.ve/hg$ cp src/mercurial-stable/contrib/hgwebdir.wsgi .

(hg)hdknr@deblen:~/.ve/hg$ vi hgwebdir.wsgi
#application = hgwebdir('hgweb.config')
# by HDKNR
CONFIG='/home/hdknr/.ve/hg/hgweb.config'
application = hgwebdir(CONFIG)

hg.deb というapache仮想サーバーを作成
(hg)hdknr@deblen:~/.ve/hg$ tree apache/
apache/
|-- conf
|   |-- httpd.conf
|   `-- httpd.conf.d
|       |-- hg.conf
|       `-- wsgi.def
|-- logs
|   |-- access.log
|   `-- error.log
`-- www
    `-- index.html
にして、
(hg)hdknr@deblen:~/.ve/hg$ ls -l /etc/apache2/sites-enabled/hg.deb.conf
lrwxrwxrwx 1 root root 41 2009-10-23 11:48 /etc/apache2/sites-enabled/hg.deb.conf -> /home/hdknr/.ve/hg/apache/conf/httpd.conf

とする。

wsgi プロセスをapacheに認識させる。

(hg)hdknr@deblen:~/.ve/hg$ vi apache/conf/httpd.conf
<VirtualHost *:80>
#Basic
    ServerAdmin admin@hg.deb
    ServerName hg.deb
    DocumentRoot /home/hdknr/.ve/hg/apache/www/

#Log
    ErrorLog /home/hdknr/.ve/hg/apache/logs/error.log
    LogLevel warn
    CustomLog /home/hdknr/.ve/hg/apache/logs/access.log combined

# Virtual Directories and Others
    Include /home/hdknr/.ve/hg/apache/conf/httpd.conf.d/wsgi.def
    Include /home/hdknr/.ve/hg/apache/conf/httpd.conf.d/*.conf

</VirtualHost>

こんな感じで、プロセス名は "v_hg"。
(hg)hdknr@deblen:~/.ve/hg$ vi apache/conf/httpd.conf.d/wsgi.def  
WSGIDaemonProcess v_hg user=www-data group=www-data threads=25  ¥
    python-path=/home/hdknr/.ve/hg/lib/python2.5/site-packages/:/home/hdknr/.ve/hg/bin

/hg という仮想ディレクトリをWSGIScriptAliasで定義。
(hg)hdknr@deblen:~/.ve/hg$ vi apache/conf/httpd.conf.d/hg.conf

WSGIScriptAlias /hg /home/hdknr/.ve/hg/hgwebdir.wsgi
<Location /hg >
    WSGIReloadMechanism Process
    WSGIProcessGroup v_hg
    WSGIApplicationGroup %{SERVER}
   Options All
</Location>

apacheリロード。

ブラウザで確認。          

ホストのMac OSからチェックアウト。
wolf:Desktop hide$ hg clone http://hg.deb/hg/home/hdknr/.ve/hg/repos/
destination directory: repos
requesting all changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
updating working directory
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
wolf:Desktop hide$ date >>repos/readme.txt
wolf:Desktop hide$ hg status repos/
M repos/readme.txt
wolf:Desktop hide$ hg commit repos -u hdknr -m "now"
wolf:Desktop hide$ hg push repos
pushing to repos
searching for changes
新たなチェンジセットはありません
wolf:Desktop hide$ cd repos/
wolf:repos hide$ hg push
pushing to http://hg.deb/hg/home/hdknr/.ve/hg/repos/
searching for changes
ssl required

                                            SSLが必要? これは後で調べてみる。                                                                                    

Filed under: Mercurial

this post is not intended to be a guide to the commands used for working with Mercurial. It is only meant to be a guide to the concepts behind the branching models.

Filed under: mercurial

Pykler says...

Doesn't it bug you when you see commit messages that say 'Updated my code to have this cool new feature', I am going to confess I do that too. However, it makes no sense. Ofcourse the code was updated, if it wasn't then you wouldn't have anything to checkin.  Similarly, 'Added a new feature to do X Y Z' is anoying. You can probably come up with millions of annoying commit messages. A better alternative would simply say 'X Y Z', if your in the habbit of formatting your commit messages (which you should), then maybe it would say.

X Y Z

Details:

    - X is explained as ... depends on ...
    - Y is a silly feature
    - Z is an ugly hack causes X and Y to be tightly coupled
    TODO: factor Z out

Since we are on the subject of commit messages, these should be coherent blocks. i.e. do not commit all your code under one commit with a messages 'Completed Development of the Application', one aspect of version control is to be able to go back in history and learn/remember what you have done. A second feature of version control, is to save your work, if you are waiting for your full application to be coded before you hit save, you have issues. So small edible byte sized commits are awesome, huge unmeaningful (sometimes hillarious, see http://github.com/jseutter/getoffmylawn for many examples of bad messages) are not.

Finally, since this is my first post about VCS, I should clarify my current situation. I am a mercurialist with hint of git. I am loving hg-git, and is hoping git-hub soon wakes up out of its coma. Bitbucket is shaping up though, and its currently looking awesome. Maybe its time for someone to write a git-hg plugin for git and return the favour. Oh and I think SVN is retarted (and you should use CVS if you want to decouple version from the control).

Filed under: mercurial

elarson says...

I went ahead and started working out how to get my todo list online. I started off pretty simple and ended up with a relatively nice system. The basic idea is that I can push my org files to my webserver and edit them. Likewise, I can pull from the server. It started with some simple paver scripts that uploaded the files and quickly became an actual application.

Here is the paver file for some of the operations:


import os
from mercurial import commands, ui, hg
from paver.easy import *
import subprocess

IONROCK_HG = 'ssh://eric@ionrock.org/path/to/todos/'
REMOTE_TODO = IONROCK_HG # '/local/dev/path/to/todos'

@task
def server():
    import cherrypy
    cherrypy.tree.graft(TodoServer(base_url='/'), '/')
    cherrypy.quickstart()

@task
def create_repo():
    cmd = subprocess.call("fab create_repo:hosts='ionrock.org'", shell=True)

@task
def commit():
    conf = ui.ui()    
    user = conf.username()
    repo = hg.repository(conf, '.')
    files = [f for f in os.listdir('.') if f.endswith('.org')]
    commands.add(conf, repo, *files)
    commands.commit(conf, repo, addremove=True, message='Syncing org files')
    commands.push(conf, repo, REMOTE_TODO)

@task
@needs('commit')
def pull():
    conf = ui.ui()    
    user = conf.username()
    repo = hg.repository(conf, '.')
    commands.pull(conf, repo, REMOTE_TODO)
    commands.update(conf, repo)

@task
@needs('commit')
def update():
    cmd = subprocess.call("fab update_todos:hosts='ionrock.org'", shell=True)
    

The server task was for starting the eventual web application for development. The commit task just automatically commits the current org files and pushes them to the remote server. The pull command does the commit first, then pulls from the remote server. These two commands uses the mercurial libraries to work with the mercurial repos.

The create_repo was just a simple task to create an mercurial repo. More interesting is the update task which updates the remote todo mercurial repo. I'm using fabric for this aspect. It was all really easy. Here is the fabfile:


from fabric import run

def update_todos():
    run('cd /home/eric/htdocs/todo && hg up')

def create_repo():
    run('cd /home/eric/htdocs/todo && hg init')

Hopefully it is really clear what is happening here. Fabric lets you run commands via ssh on a remote server.

The actual todo server is a bit longer but also pretty simple.


import os
import re
import posixpath as path
import difflib
from selector import Selector
from webob import Response, Request
from webob.exc import *
from mercurial import commands, ui, hg
import datetime


class TodoFile(object):
    def __init__(self, fn):
        self.fn = fn
        self.html_diff = difflib.HtmlDiff()
        self.diff = difflib.Differ()
        self.matcher = difflib.SequenceMatcher()
        lines = [l for l in open(fn, 'r')]
        self.matcher.set_seq2(lines)

    def _hg(self):
        conf = ui.ui()
        user = conf.username()
        repo = hg.repository(os.path.dirname(self.fn))
        return conf, repo, user

    def __str__(self):
        return ''.join(self.read())
    
    def read(self):
        return [l for l in open(self.fn, 'r')]

    def write(self, new):
        f = open(self.fn, 'w')
        clean = re.sub('\r', '', new)
        f.write(new)
        f.close()
        conf, repo, user = self._hg()
        date = datetime.datetime.now().strftime('%m-%d-%y %H:%M')
        commands.commit(conf, repo, message='Web write on %s' % date)
        
    def is_different(self, new):
        self.matcher.set_seqs(new.split('\n'), self.read())

    def diff_txt(self, new):
        return list(difflib.context_diff(new.split('\n'), self.read()))

    def diff_html(self, new):
        return self.html_diff.make_file(self.read(), new.split('\n'))        
    

class TodoStore(object):
    def __init__(self, directory):
        self.dir = os.path.abspath(directory)

    def get_todo(self, name):
        for fn in os.listdir(self.dir):
            if fn.endswith('.org') and (fn[:-4] == name):
                return TodoFile(os.path.join(self.dir, fn))
        return false

    def all(self):
        return [fn[:-4] for fn in os.listdir(self.dir) if fn.endswith('.org')]


class Auth(object):
    def __init__(self, creds, login_url, success_url=None):
        self.login_url = login_url
        self.success_url = success_url
        self.creds = creds

    def __call__(self, f):
        def func(env, sr):
            sess = env['beaker.session']
            if sess.get('auth.user'):
                return f(env, sr)
            req = Request(env)
            sess['auth.after_login_url'] = req.url
            sess.save()
            return HTTPSeeOther(location=self.login_url)(env, sr)
        return func

    def login(self, env, sr):
        res = Response()
        sess = env['beaker.session']
        flash = sess.get('flash', '')
        if flash:
            sess['flash'] = ''
            sess.save()
        res.write('''<div>%s</div>
        <form action="%s" method="post">
          <label for="username">Username</label>
          <input type="text" name="username" value=""><br />
          <label for="password">Password</label>
          <input type="password" name="password" value=""><br />
          <input type="submit" value="login" />
        </form>''' % (flash, self.login_url))
        return res(env, sr)

    def handle_login(self, env, sr):
        req = Request(env)
        post = req.POST
        sess = env['beaker.session']        
        if post.get('username') and post.get('password'):
            if self.creds.get(post['username']):
                if self.creds[post['username']] == post['password']:
                    sess['auth.user'] = post['username']
                    url = sess.get('auth.after_login_url', self.success_url)
                    sess.save()
                    return HTTPSeeOther(location=url)(env, sr)
        sess['flash'] = 'Error logging in.'
        sess.save()
        return HTTPSeeOther(location=self.login_url)(env, sr)
            

class TodoServer(object):

    def __init__(self, **config):
        self.conf = {
            'todo_dir': os.path.dirname(os.path.abspath(__file__)),
        }
        self.conf.update(config or {})

        self.auth = Auth(self.conf.get('creds', {}),
                         self.url('login'),
                         self.url())
        

        self.store = TodoStore(self.conf['todo_dir'])

        self.router = Selector([
            ('[/]', {'GET': self.listing}),
            ('/login[/]', {
                'GET': self.auth.login,
                'POST': self.auth.handle_login
            }),
            ('/{name}/edit[/]', {
                'GET': self.edit,
                'POST':  self.auth(self.update)
            }),
            ('/{name}[/]', {'GET': self.read}),
        ])

    def url(self, extras=None):
        extras = extras or ''
        if isinstance(extras, list):
            extras = '/'.join(extras)
        return path.join(self.conf['base_url'], extras)

    def _header(self):
        return '''<html><head>
        <title>org todo server</title>
        <style type="text/css">
        body {
            font-size: 2em; font-family: sans-serif;
        }
        </style>
        '''

    def _footer(self):
        return '''</body></html>'''

    def edit(self, env, sr):
        res = Response()
        req = Request(env)
        name = req.urlvars['name']
        td = self.store.get_todo(name)

        res.write(self._header())
        res.write('''
        <form action="%s" method="post">
        <input type="submit" name="submit" value="save" /><br />        
        <textarea rows="50" cols="80" name="new_body">%s</textarea>
        </form>
        ''' % (self.url('%s/edit' % name), str(td)))
        res.write(self._footer())
        
        return res(env, sr)

    def update(self, env, sr):
        req = Request(env)
        name = req.urlvars['name']
        new_body = req.POST['new_body']
        todo = self.store.get_todo(name)
        todo.write(new_body.strip())
        location = self.url('%s' % name)
        return HTTPSeeOther(location=location)(env, sr)

    def read(self, env, sr):
        res = Response()
        req = Request(env)
        name = req.urlvars['name']

        res.write(self._header())
        res.write('''
        Home | Edit
        <hr />
        <pre>''' % (self.url(), self.url('%s/edit' % name)))
        td = self.store.get_todo(name)
        res.write(str(td))
        res.write('</pre>')
        res.write(self._footer())
        
        return res(env, sr)

    def listing(self, env, sr):
        res = Response()

        res.write(self._header())
        res.write('<ul>\n')
        for f in self.store.all():
            res.write('<li>%s</li>\n' % (self.url(f), f))
        res.write('</ul>\n')
        res.write(self._footer())
        
        return res(env, sr)

    def __call__(self, env, sr):
        return self.router(env, sr)


This is a WSGI app simply because I'm using WSGI for my main application. I save a bit of memory by running all my smaller apps via one WSGI server (CherryPy), which makes a difference as I use a VPS.

One observation I made is that things would have been simpler had I been able to use CherryPy. Things like sessions, form processing and even URL routing would have been built in and made the whole thing a lot simpler in terms of dependencies and actual code.

This also made me realize what the problem is building applications with WSGI. You really need a framework. I don't mean Pylons, web.py or some other WSGI framework. But you will undoubtedly write some glue code to help handle things like request and response objects that help to deal with form handling, sessions and cookies. It is nice to know that it is so easy to create these micro frameworks, but at the same time, it is clear that people would be making bad decisions. I only say that because I'm one of them.

When I think of the micro frameworks I've written throughout the past few years, it is clear that I've had to experiment quite a bit. WebOb was a helpful library for sure, but the API you build translating the request to a WebOb Request means breaking WSGI at some level. That means that you've lost the advantages of WSGI as an API for your application. In my mind, it makes me wonder why then the app was written with WSGI in the first place as there is a solid and proven API already built with something like CherryPy.

I doubt I'll rewrite my whole site anytime soon, but if I do, the application framework will most definitely revolve around the framework rather than WSGI. The advantages that I believed were present ended up being much less than I thought. Having a tool like CherryPy manages to take care of the generic aspects enough while letting me use more opinionated aspects such as templating or databases. You could most certainly substitute your framework of choice, but for me CherryPy is making more and more sense.

Filed under: mercurial

elarson says...

I'm going to have to go back and see how I can avoid laying a big fat patch bomb on a repo and I'm not happy about it. There is no one to blame but myself. That doesn't make it any nicer. My big issue is that for all the cool features of Mercurial there is a consistent front loading requirement. You cannot simply work and then later construct your commits that you'll be pushing. MQ does help with this sort of thing and I'm going to have to find out just how much tomorrow, but it would have been really nice if I could have started coding and whan I finished have a convenient way to go through all the files and commit them in reasonable chunks.

The astute reader will recognize that this issue really just a sign of bad DVCS habits and I'm not about to argue otherwise. Still, I'm very much a part of the "not a great coder" club, and as such, seem like a good candidate for how to help out the normal developers using these powerful tools. One might also suggest that I open a ticket, or even better, contribute a patch. Again, my "not a great coder" club membership explicitly states that any gripes need to stay far away from those folks getting a lot of work done (a la the mercurial devs), hence I'm totally fine leaving my whining here on my blog. My bet is bringing it up here will do more to improve my own habits than suggesting to others they are real problems.

Next time I'm really going to do a better job manaing my patches. Feel free to hold my feet to the fire in the future seeing how I've done.

Filed under: mercurial

moriza says...

A base, from a process I called sublimation, where I combined completed works by scanning with minimal manipulation, then using it as a base for a freehand work. In this sample, I used elements from three separate work. I then printed a glycle edition of this base to be drawn on with pen to complete the work. I miss doing this kind of work, but it takes a lots of time.
**On top is a scan of my etching (which it self a sublimation work, of color pencil on a print), middle part from my water color painting and bottom part is from one of my large acrylic painting. 

Filed under: Mercurial

SpookyET says...

On Unix-based and Unix-inspired operating systems such as Linux, one often has hidden configuration files in his home directory. In most unices, your home directory is /home/username; on Apple Macintosh, it is /Users/username. These files are created by the operating system, applications, programs, and most often, manually. Dotfiles.org is a popular website for finding user-uploaded configuration files. Creating your own configuration files is tedious, error prone, and requires many hours or even days of reading documentation or man pages. It is best to embrace and extend by copying and pasting from Dotfiles.org.

Even though this article is primarily targeted at those which are comfortable with the command line since these configuration files are mostly for command line programs, it also benefits those that are not. For example, on Mac, most applications store their preference files in /Users/username/Library/Preferences. One could put said directory under version control. Should an option be changed in an Application for the worst, and the user does not remember how to change it back, all he must do is close the application, revert the directory to the base state and relaunch the application. 

Since creating these files is a labourious process, it is best to mange and store configuration files in a repository off site. You will be able to track changes and revert if a new configuration change breaks programs. Any version control system may be used. The most popular open-source systems are SubversionGitMercurial, and Bazaar.

All have advantages and disadvantages. If you are on Ubuntu, you will most likely use Bazaar. It is developed by Canonical, the makers of Ubuntu, and you will use it with Launchpad. Support should be easy to find in the Ubuntu Forums. Mercurial is independently developed and the main competitor to Git. It is faster and more popular than Bazaar. The main hosting service is BitBucket. It has a decent interface. Even though it is more popular, there is less support for it than for Bazaar. It does not have a big community such as Ubuntu. Git was created for the Linux kernel by Linux Tovarlords. As such, it is very popular, not to mention, abnormally fast. Support can be easily found.  Though, it does not have the best CLI interface, and there is no decent GUI for it, you will love GitHub. Probably 70% of the Git repositories are hosted there.

For this tutorial, we will use Subversion, which has been in the wild for almost a decade. It is also pre-installed on Mac OS X 10.5 Leopard. There are many  graphical user interface clients for it. On Mac, there are Versions, which has recently received the Apple Design Award 2009, and Cornerstone, on Windows TortoiseSVN, on Linux eSVNRapidSVN (cross platform), KDESvn, and many others. There are also many repository hosting companies with pretty and usable interfaces. Be aware that this article is not about version control. It discusses the bare minimum required for this tutorial to work. You may read a more in depth, but by no means comprehensive, tutorial on Subversion in an article written by Christ Nagele, one of the people behind Beanstalk, Subversion for Designers.

First, we will create a directory to store the configuration files. Traditionally, it is called etc, and Linux users may want to create /home/username/etc. I chose to call it Preferences since it better matches the Mac naming conventions: /Users/sorin/Preferences.

Next we have to move the configuration files from  /Users/sorin to /Users/Sorin/Preferences. We can use the command line or we can use Finder. Using Finder also requires the temporary use of the command line because Apple do not believe that Mac users should be able to easily access hidden files. Hidden files in Unix are called dot files because they begin with a dot: .bashrc. This is the configuration file for Bash, the shell that runs inside the Terminal. 

We must enable hidden files in Finder. Launch Applications > Utilities > Terminal and paste:

defaults write com.apple.finder AppleShowAllFiles TRUE; killall Finder

You can reverse the change later by pasting:

defaults write com.apple.finder AppleShowAllFiles FALSEkillall Finder

Once you have enabled hidden files, select the configuration files and folders you wish to put under version control and drag them to the Preferences folder. Then remove the dot from in front of the file to make them unhidden. From now own, you will not have to enable hidden files to easily find and edit them. They will also be displayed in Spotlight searches.

It is much easier to move and rename the files from the command line. Most likely you will not want to move all the hidden files and folders. There can be tens of them and not all are important. Select the ones you wan to move by appending file names before the semi-colon in the first line. Then paste this in Terminal.

for entry in .bashrc .vimrc .profile
do

new_name=`echo $entry | sed -e 's/\.//g'`
mv $entry Preferences/$new_name

done

Regardless of which methods you chose, the result should be similar to this screen-shot.

Next, we must create symbolic links, or shortcuts, in the home directory to point to the new location of the configuration files. I have written a script that automatically creates the symbolic links. It is safe to use. It backs up files that already exist in a directory called .deploy_backup in your home directory instead of overwriting. Just place deploy.rb in Preferences and execute it in Terminal by typing ./deploy.rb. Do not forget to change its permissions to an executable file first with chmod u+x deploy.rb.

You will see symbolic links in your home folder.

We have not taken such effort to just be able to easily edit and search configuration files with Spotlight; we want to store them offsite on someone else's server to make sure we never lose them. Get yourself a free Subversion repository hosting account at Beanstalk. It is a very easy to use application.

Once, you have created an account, you can access it online at http://username.beanstalkapp.com. Log-in then go to the Repositories tab and create a repository. I called mine personal. You may name it anything you wish. The repository is accessible via Subversion at http://username.svn.beanstalkapp.com/repositoryname. You will be prompted for your username and password. We have to import our Preferences folder into the repository. We will use the svn import command in Terminal to import all files into the repository.  Once the import process is done, unfortunately, due to the way Subversion works, our configuration files have been imported, but are not yet tracked. We have to check them out first. Since Subversion does not overwrite existing files, we have to check them out in a temporary location.  

cd ~/Preferences;
svn import http://username.svn.beanstalkapp.com/repositoryname -m "Initial import."
cd ..
svn checkout http://username.svn.beanstalkapp.com/repositoryname/ Preferences2
rm -rf Preferences
mv Preferences2 Preferences

Alternatively, in Versions, we can go to File > Import. Select the Preferences folder and click Import. Then click the Checkout icon to checkout our files to Preferences2. Do not forget to edit the bookmark created to point to Preferences and not Preferences2.

Versions makes it easy to import and checkout files.

Once your repository is set, you are free to modify the configuration files as you see fit and never have to worry about making detrimental changes. You can always revert to the older version. In the screen-shot bellow, I have modified vimrc to change the Terminal title to 'Shell' when it exists instead of 'Thanks for flying Vim'. This is reflected by the letter 'M' at the begging of the line. Versions reflects the change by displaying a pencil icon next to the file.

If you have made a bad change, click the Revert icon on the right.
Once you are ready to commit your changes, you can use either use svn commit -m "<message>" in Terminal or use Versions, which is much easier if want to commit only the changes to vimrc (not shown in the screen-shot) by selecting just that file as opposed to committing all tracked files.
Always write meaningful commit messages to easily find changes later. Do not follow my example.

If  you want to use my configuration files, you may get them at http://sorin.svn.beanstalkapp.com/personal/trunk/Preferences. Just execute deploy.rb. Be advised that MacPorts and iTerm are required as well as the following ports (packages). The .bashrc should work on Linux without problems. I have encapsulated Mac-only settings. If you find bugs or improvements that can be made, please don't hesitate to email me.

bash-completion @1.0_1 (active)
coreutils @7.4_0+with_default_names (active)
ctags @5.7_0 (active)
fortune @6.2.0-RELEASE_0 (active)

Disclaimer I am not associated with Wildbit, makers of Beanstalk nor Pico+Sofa, makers of Versions. I actually use Git, and you may view my repository at GitHub.

Filed under: mercurial