<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0" 
   xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" 
   xmlns:html="http://www.w3.org/1999/html" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
<channel>
   <title>James Westby</title>
   <link>http://jameswestby.net/weblog</link>
   <description></description>
   <language>en</language>
   <copyright>Copyright 2006-2008 James Westby</copyright>
   <ttl>60</ttl>
   <pubDate>Sun, 22 Feb 2009 13:19 GMT</pubDate>
   <managingEditor>jw+blog@jameswestby.net</managingEditor>
   <generator>PyBlosxom http://pyblosxom.sourceforge.net/ 1.4.3 01/10/2008</generator>
<item>
   <title>Sandwiches</title>
   <guid isPermaLink="false">bzr/03-sandwich</guid>
   <link>http://jameswestby.net/weblog/bzr/03-sandwich.html</link>
   <description><![CDATA[
<div class="document">
<p><a class="reference external" href="http://rickroll.it/9d6422">Mr LeSage</a>, I just happened to run <tt class="docutils literal">bzr plugins</tt> today, and noticed this:</p>
<pre class="literal-block">
.
.
sandwich
    (no description)
.
.
</pre>
<p>Curious as to what the hell that was, I ran the command again with <tt class="docutils literal"><span class="pre">-v</span></tt> and
saw that it was installed in my <tt class="docutils literal"><span class="pre">~/.bazaar/plugins/</span></tt> directory. I opened the
file and found this that I wrote a few months ago:</p>
<pre class="literal-block">
from bzrlib.commands import Command, register_command

class cmd_make_me_a_sandwich(Command):

    def run(self):
        self.outf.write(&quot;What? Make it yourself.\n&quot;)

class cmd_sudo_make_me_a_sandwich(Command):

    def run(self):
        self.outf.write(&quot;Okay.\n&quot;)

register_command(cmd_make_me_a_sandwich)
register_command(cmd_sudo_make_me_a_sandwich)
</pre>
<p>Not quite what you were after though. That would be this plugin:</p>
<pre class="literal-block">
class SandwichCommand(Command):

    def run(self, **kwargs):
        for name, arg in kwargs.items():
            if arg != name:
                self.outf.write(self.fail_message + &quot;\n&quot;)
                return 1
        self.outf.write(self.success_message + &quot;\n&quot;)
        return 1

class cmd_make(SandwichCommand):

    takes_args = [&quot;me&quot;, &quot;a&quot;, &quot;sandwich&quot;]
    fail_message = &quot;Make you a what?&quot;
    success_message = &quot;What? Make it yourself.&quot;

class cmd_sudo(SandwichCommand):

    takes_args = [&quot;make&quot;, &quot;me&quot;, &quot;a&quot;, &quot;sandwich&quot;]
    fail_message = &quot;Of course, but what do you want me to do?&quot;
    success_message = &quot;Okay.&quot;

register_command(cmd_make)
register_command(cmd_sudo)
</pre>
<p>I'm still none the wiser as to why I wrote that plugin in the first place
though.</p>
</div>

]]></description>
   <category domain="http://jameswestby.net/weblog"></category>
   <pubDate>Sun, 22 Feb 2009 13:19 GMT</pubDate>
</item>
<item>
   <title>bzr-upload</title>
   <guid isPermaLink="false">bzr/02-bzr-upload</guid>
   <link>http://jameswestby.net/weblog/bzr/02-bzr-upload.html</link>
   <description><![CDATA[
<div class="document">
<p>On Friday <a class="reference external" href="https://launchpad.net/bzr-upload">bzr-upload</a> was officialy <a class="reference external" href="http://beuno.com.ar/archives/80">announced</a>. In the blog
announcement Martin tells the story of how this plugin was born. I'm
proud to say &quot;I was there!&quot;. I was sat at the table with them that
evening as they discussed what was wanted, and what was possible. This
was just one of the great things about the last sprint for me, and I was
only there for two days.</p>
<p>Very often on the #bzr IRC channel we have users asking why bzr doesn't
update the working tree on a remote machine, and what they can do about
this. Very often it turns out that they are web developers who are looking
to deploy a website, rather than just host the branch, and so the
normal behaviour is kind of the opposite of what they want.</p>
<p>John wrote the <a class="reference external" href="https://launchpad.net/bzr-push-and-update">push-and-update</a> plugin to help with this, but it
didn't fulfil all the needs, and requires ssh access, where web developers
sometimes only have ftp access.</p>
<p>While bzr-upload does have some corner cases to be wary of, it's a great thing
to have available. If you are web developer who is looking for a version
control system for your code then consider bzr, it will hopefully suit
your workflow very well.</p>
<p>Now, watch out for Martin's improvements to <a class="reference external" href="https://launchpad.net/loggerhead">loggerhead</a>, and Vincent's
improvements to his kitchen.</p>
</div>

]]></description>
   <category domain="http://jameswestby.net/weblog"></category>
   <pubDate>Tue, 24 Jun 2008 19:38 GMT</pubDate>
</item>
<item>
   <title>Revision numbers</title>
   <guid isPermaLink="false">bzr/01-revision-numbers</guid>
   <link>http://jameswestby.net/weblog/bzr/01-revision-numbers.html</link>
   <description><![CDATA[
<div class="document">
<div class="section" id="revision-numbers-vs-revision-ids">
<h1>Revision numbers vs. revision ids</h1>
<p>One thing that Bazaar does a little different to the other distributed
systems is to give every revision a revision number. Some people don't
like this as the revision numbers are global, that means that the revision
number of a revision in my branch does not necessarily match the
number that it was given in your branch. Some people say that this
makes bzr somehow &quot;less distributed.&quot; This is not the case at all,
you just need to be careful to be clear what branch you are referring
to, i.e. say &quot;revision 315 on branch <a class="reference external" href="http://">http://</a>...&quot;, rather than just
&quot;revision 315&quot;.</p>
<p>This is a little dangerous in that the branch may have it's revision
history changed, for instance by uncommitting and then committing
again. If that may happen then you should use revision ids, which
you can find from &quot;bzr log --show-ids&quot;.</p>
<p>Why do number the revisions at all then? One reason is simply
that some people find revision ids ugly, and may be scared off
by them.</p>
<p>Another reason is that they are shorter to type. git folks will
tell you can use the first few characters of the revision id, and
git will work out what revision you mean. However these shortened
ids are not necessarily stable over a long period of time, and
so again, if you are worried you should use the whole thing.</p>
<p>The third reason is that the numbers can give some sense of the
order of the revisions in your branch. If I say talk about
revisions &quot;3445abe&quot; and &quot;b27ac9&quot; then you don't know which
is earlier in history. If I refer to revisions 345 and 532 then
it is immediately obvious (providing that I am only referring to
a single branch).</p>
<p>The advantages I have outlined are small, but they could be
valuable at times, and you always have the revision ids to fall
back on if you require them.</p>
</div>
<div class="section" id="numbering-merged-revisions">
<h1>Numbering merged revisions</h1>
<p>Along with numbering the mainline bzr also numbers merged revisions
using a dotted numbering scheme. This means that your mainline
revisions are &quot;1&quot;, &quot;2&quot;, &quot;3&quot;, as you would expect, but any merged
revisions are given three digit numbers, e.g. &quot;2.1.3&quot;.</p>
<p>The numbering scheme has a couple of nice properties, the most
notable of which is that it is &quot;stable&quot;, this means that once
I have numbered a merged revision with respect to a certain mainline
it cannot be effected by any addition I make to the revision history.
This means that any commits, pulls or merges that I do will not
change any of the existing revision numbers, but they will add
numbers to any new merged revisions such that they will not be
the same as any number already used.</p>
<p>The current algorithm used for this involves looking at the whole
history of the branch to number the revisions, which is obviously
undesirable.</p>
<p>On the last evening of the sprint last week myself and John
were discussing the numbering scheme, and thinking about
possible algorithms to do the numbering that would be more
efficient.</p>
<p>We had the following inputs:</p>
<blockquote>
<ol class="arabic simple">
<li>The revsision id you are trying to give a dotted number
for.</li>
<li>The tip of the mainline that you are numbering against.</li>
<li>The revision number of that mainline revision.</li>
<li>A map of revision_id -&gt; parents.</li>
</ol>
</blockquote>
<p>And you are asked to provide the revision number for the specified
revision. Any other numbering that you may be able to do along the
way would be a bonus.</p>
<p>The fact that all we are given to get the information we need is
a map telling us the parents of a revision id means that we cannot
ask the question &quot;what are all the children of this revision?&quot;</p>
<p>I don't really want to explain the numbering scheme here, as it
is a little long-winded to do so. The outline is that for the first
digit you find the intersection of the target revision's left hand
ancestry with the mainline, and use its revision number. For the
second digit you find all of the branches that originated at the
revision found in the first part, and then number them by
the order that they merged back in to mainline. The third
digit is then just the place of the revision in its own part
of one of these branches.</p>
<p>Notice the second step there. Remember that we are not able to
retrieve the children of any revision? That means that we must
work backwards from our mainline to do this. This is where
the real complexity comes in, and it appears as though it is
necessary to search a reasonable amount of history to
calculate this part.</p>
<p>After the discussion with John I had a reasonable idea of how
such an algorithm would work, and yesterday I posted a <a class="reference external" href="http://thread.gmane.org/gmane.comp.version-control.bazaar-ng.general/38388">first
draft</a> of that to the mailing list. We have found some
problems with it, and haven't benchmarked it yet to see if it
is actually an improvement, but hopefully it will evolve and
prove to be faster.</p>
</div>
<div class="section" id="displaying-logs-and-history-emphasis">
<h1>Displaying logs, and history emphasis</h1>
<p>The revision numbering code has a very close relationship,
and also interacts with it in an awkward way from a
performance standpoint. This lead to John explaining
to me how the logs are generated in more depth.</p>
<p>When bzr produces logs by default it emphasises the left
hand parent to produce your mainline. It then indents any
revisions that you merged:</p>
<pre class="literal-block">
&gt;       -----------------------------------------------------------
&gt;       revno: 3270
&gt;       committer: Canonical.com Patch Queue Manager &lt;pqm&#64;pqm.ubuntu.com&gt;
&gt;       branch nick: +trunk
&gt;       timestamp: Thu 2008-03-13 00:40:30 +0000
&gt;       message:
&gt;         (Adeodato Simo) Add a space after &quot;revision-id:&quot; in log output.
&gt;          -----------------------------------------------------------
&gt;          revno: 3257.2.1
&gt;          committer: Adeodato Simó &lt;dato&#64;net.com.org.es&gt;
&gt;          branch nick: foo
&gt;          timestamp: Sun 2008-03-09 23:06:47 +0100
&gt;          message:
&gt;            Add a space after &quot;revision-id:&quot; in log output.
&gt;       -----------------------------------------------------------
&gt;       revno: 3269
&gt;       committer: Canonical.com Patch Queue Manager &lt;pqm&#64;pqm.ubuntu.com&gt;
&gt;       branch nick: +trunk
&gt;       timestamp: Wed 2008-03-12 23:08:34 +0000
&gt;       message:
&gt;         (Daniel Watkins) Add a --revision option to 'bzr push'
&gt;           -----------------------------------------------------------
&gt;           revno: 3256.1.5
&gt;           committer: Daniel Watkins &lt;D.M.Watkins&#64;warwick.ac.uk&gt;
&gt;           branch nick: push-r
&gt;           timestamp: Sun 2008-03-09 18:41:31 +0000
&gt;           message:
&gt;             Added NEWS entry.
</pre>
<p>To do this it must decide which revisions are present in the history
of one revision, but not in the history of its left hand parent.
To do this it starts off two history walkers in parallel, one
walking the history of the first revision, the second walking the
history of the parent. The first walker then stops walking down
a particular line of history when the second &quot;claims&quot; it, once
the first walker has no more lines of history to walk it returns
its group of revisions, and the log formatter code then displays them
indented as necessary to match the history.</p>
<p>This is a much more complex process than that you get with &quot;git log&quot;,
in which the revisions are produced in just <a class="reference external" href="http://news.gmane.org/gmane.comp.version-control.git">date order</a>. There is
a &quot;--topo-order&quot; option to git log, but that just ensures that all
parents are output before their children. It doesn't ensure that
all parents not in the ancestry of the left-hand parent are shown
before the left-hand parent. The work to ensure that is significantly
more than that done to provide &quot;--topo-order&quot;.</p>
<p>This display makes it easy to see what work was done on a branch,
and when those changes entered your branch. This is one reason
why bzr's merge doesn't fast-forward by default (&quot;bzr merge --pull&quot;
will do this for you if you like). This means that you can always
instantly identify which work came from another branch and have
them tied together.</p>
<p>Always having merge commits means that &quot;bzr log --short&quot; and
&quot;bzr log --line&quot; can give you a good summary of what happened
on your branch, the commits you did, and the things that you
merged. It preserves a mainline for you in the left hand
ancestry, which means that you can always see what happened
in that particular branch. &quot;bzr pull&quot; then gives you a mirror
of another branch, and the left hand ancestry tells you what
happened in that branch.</p>
<p>The indentation of the merged commits (and the fact they
disappear with &quot;--short&quot; and &quot;--line&quot;) means that mentally
they become of lesser importance. You see &quot;merged performance
work from Emma's branch&quot;, rather than all of the commits that
you got from her. They are still there to look at if you want,
but they can be ignored at most times.</p>
<p>This means that you don't have to spend time rewriting history
to be clean if you don't want to. You don't have the
history right in your face either way, though there can
still be value in having a clean history. However rewriting
history is not what some people <a class="reference external" href="http://lists.debian.org/debian-devel/2008/02/msg01053.html">want</a> to <a class="reference external" href="http://lists.debian.org/debian-devel/2008/03/msg00236.html">do</a>, and causes
problems for those who base their work on yours.</p>
</div>
</div>

]]></description>
   <category domain="http://jameswestby.net/weblog"></category>
   <pubDate>Thu, 13 Mar 2008 16:49 GMT</pubDate>
</item>
<item>
   <title>Version control systems and text editors</title>
   <guid isPermaLink="false">bzr/00-git-vim</guid>
   <link>http://jameswestby.net/weblog/bzr/00-git-vim.html</link>
   <description><![CDATA[
<div class="document">
<p>So apparently &quot;<a class="reference external" href="http://chistera.yi.org/~adeodato/blog/entries/2008/03/05/one_day_with_git.html">learning git is like learning vim</a>&quot;. Putting aside
the incremental learning aspects of this, and stretching the point
a little, will you allow me to say &quot;git is like vim&quot;?</p>
<p>We all understand there is no way in which you would mandate that
all contributors use vim. You wouldn't want to lose all of those
valuable contributions from emacs users of course. However, you
still wouldn't dream of mandating the use of one of these two
editors. Why should your choice as project maintainer constrain
the way in which others want to work?</p>
<p>Obviously it is quite difficult to enforce this editor rule. For
a start there is nothing in a plain text file that tells you what
editor was used to create it. More importantly though, the
contributor's choice of editor doesn't matter to you. If they send
you a plain text file then your editor will handle it just as well
as theirs.</p>
<p>This is where version control differs from editors. When using the
version control system to move code around it tends to dictate the
client you use to access it, so one person's decision tends to
impact on others.</p>
<p>Is the solution therefore to work towards a situation we have
that is similar to that we have with text editors, where the
<a class="reference external" href="http://www.kernel.org/pub/software/scm/git/docs/git-fast-import.html">interchange format</a> is understood equally well by all of the tools?
Do we spend time developing <a class="reference external" href="http://wingolog.org/archives/2008/03/11/using-newfangled-version-control-systems-from-emacs">wrappers</a> for <a class="reference external" href="http://kitenet.net/~joey/code/mr/">each use</a> that allow
us to ignore the fact that we are using different systems?</p>
<p>Recently there has been <cite>work</cite> done to make bzr support the
git-fast-import format. This would then be the start of an
interchange format that all tools could use to communicate.
However, the problem is that the representations used in one
system start to bleed. For instance, bzr supports ghosts, and we
are currently discussing the adding support to the format
to represent them. However git doesn't support them, and as
such there will be know way to complete a round trip of
bzr-&gt;git-&gt;bzr when there are ghosts involved.</p>
<p>So, what about the other solution? Creating wrappers that
allow the user to not care what VCS they are using and just
get the job done? I think this is useful to a point. It will
be great for some people who just want to do really simple
things on lots of projects (for instance in Debian). However
the tools are necessarily catering to the lowest common
denominator, they won't support any of the unique things
that make each system great.</p>
<p>Bazaar has foreign branch support (most notably <a class="reference external" href="https://launchpad.net/bzr-svn">bzr-svn</a>)
which allow you to access another system as if if were bzr.
This is almost completely transparent (&quot;bzr branch svn://&quot;
makes it clear what the project is hosted in), in contrast
to git-svn. The latter adds a new command that allows you to
do the svn specific parts (setting up the repository, committing
back to svn). In contrast bzr-svn uses the normal bzr commands
for (almost[1]) everything, meaning you only need to learn the
one tool. git-svn is still a great tool, but it certainly makes
you realise that you are not dealing with pure git.</p>
<p>The competition between the systems has been great for every
one of them. However, it seems like we will be stuck with different
systems for the forseeable future, so we should work hard on
making them work well together to ease the pain on the users.
I think that many of the supporters of distributed version
control would say that it is better for you to be using any
of them than none of them, but the fractured and unstable
landscape we have now is causing a resistance in people to
make the switch.</p>
<table class="docutils footnote" frame="void" id="id1" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label">[1]</td><td>It currently adds svn-push for doing a push that creates
a new branch in svn, but this is only a temporary thing,
&quot;bzr push&quot; will be able to do this at some point. The other
commands that are added are for extra things that the core
bzr is not meant to deal with.</td></tr>
</tbody>
</table>
</div>

]]></description>
   <category domain="http://jameswestby.net/weblog"></category>
   <pubDate>Wed, 12 Mar 2008 01:25 GMT</pubDate>
</item>
</channel>
</rss>
