VCS comparison table

Carl Worth cworth at
Sun Oct 22 15:25:41 BST 2006

At Sun, 22 Oct 2006 11:56:32 +0200, "=?ISO-8859-1?Q?Erik_B=E5gfors?=" wrote:
> Consider the following
> bzr branch mainline featureA
> cd featureA
> hack hack; bzr commit -m 'f1'; hack hack bzr commit -m f2; etc
> No I want to merge in mainline again
> bzr merge ../mainline; bzr commit -m merge
> hack hack; bzr commit -m f3; hack hack bzr commit -m f4; etc

Thanks for sharing this example. I think when we look at concrete
things that the tools actually let you do, we have a better
conversation. Plus, this example highlights some very interesting
differences between the tools.

So here is a complete sequence of git commands to construct the
scenario (even the extra hacking in mainline):

	mkdir gittest; cd gittest
	git init-db
	touch mainline; git add mainline; git commit -m "Initial commit of mainline"
	git checkout -b featureA
	touch f1; git add f1; git commit -m f1
	touch f2; git add f2; git commit -m f2
	git checkout -b mainline master
	touch sd; git add sd; git commit -m "something done in mainline";
	touch se; git add se; git commit -m "something else done in mainline";
	git checkout featureA
	git pull . mainline
	touch f3; git add f3; git commit -m f3
	touch f4; git add f4; git commit -m f4

For reference, here's the same with bzr:

	mkdir bzrtest; cd bzrtest
	bzr init-repo . --trees
	bzr init mainline; cd mainline
	touch mainline; bzr add mainline; bzr commit -m "Initial commit of mainline"
	cd ..; bzr branch mainline featureA; cd featureA
	touch f1; bzr add f1; bzr commit -m f1
	touch f2; bzr add f2; bzr commit -m f2
	cd ../mainline/
	touch sd; bzr add sd; bzr commit -m "something done in mainline"
	touch se; bzr add se; bzr commit -m "something else done in mainline"
	cd ../featureA
	bzr merge ../mainline/; bzr commit -m "merge"
	touch f3; bzr add f3; bzr commit -m f3
	touch f4; bzr add f4; bzr commit -m f4

[As has recently been pointed out, the tools really are more the same
than different, and I think the above illustrates that.]

> right now, I would have something line this in the branch log

OK. So here is a difference in the tools. With git, you don't get the
indentation for the "non-mainline" commits. This is because git
doesn't recognize any branch in the DAG to be more significant than
any other. Instead, git provides a flat, and (heuristically)
time-sorted view of the commits. (It's heuristic in that git just uses
the time stamps in the commit objects---but it doesn't actually care
if these are totally "wrong"---git knows that there is no global

That said, git does store an order for the parent edges of each
commit, and this order is assigned deterministically by the commands
that create merge commits. So someone could use git carefully, (which
it seems people are doing with bzr), to preserve "mainline as first
parent" and someone could write a modified git-log that would do

But even without any of that manual care for creating a "mainline",
git already provides a very easy way to see the "mainline" view
anyway. See below.

> In this view,I can easily see what was part of this feature branch,
> because the commits that belongs to the feature branch are not
> indented, and they have a "branch nick" of "featureA".  I can also
> easily see what comes from other branches.

Ah, I hadn't realized that bzr commits stored an "originating branch"
inside them. Git commits definitely do not have anything like
that. And as I said above, there's no indentation in git-log, so the
commits from separate branches are "mixed up". But see below.

> I can also run bzr log with --line or --short which shows you only the
> commits made in this branch and not the once that are merged in.  So
> with --line I would get something line
> Erik Bågfors 2006-10-19 f4
> Erik Bågfors 2006-10-19 f3
> Erik Bågfors 2006-10-19 merge
> Erik Bågfors 2006-10-19 f2
> Erik Bågfors 2006-10-19 f1
> Which will give me a good view of what has been done in this feature
> branch only.

Thank you. You've provided a concrete example of something to do,
("see commits that belong to a feature branch"), that is really very
practical and useful. And bzr achieves this ability by adopting a
"mainline is special" treatment in bzr. This special treatment
influences or directly causes many of the things in bzr that we've
been discussing:

 * mainline commits get special treatment from revision numbers
   (in old days, they're the only commits to have revision
   numbers---more recently they're the only commits to get non-dotted
   revision numbers)

 * bzr adds empty merge commits instead of fast-forwarding since it
   needs a new "mainline" commit

 * users have to be careful about merge direction to avoid
   accidentally going the "wrong" way

 * users are discouraged from using the "give me their DAG" pull
   command since it would scramble their local view of what "mainline"

I've been arguing that all of these impacts are dubious. But I can
understand that a bzr user hearing arguments against them might fear
that they would lose the ability to be able to see a view of commits
that "belong" to a particular branch.

But git provides that view perfectly well, and it's what git users
work with all the time. It doesn't require any special treatment of
one commit parent vs. another, nor storage of "originating branch" in
the commit, nor the user taking any care whatsoever about which
direction merges are performed, (nor "who" does the merge).

And as a bonus, the command-line for this view is really simple:

	git log mainline..featureA

This gives a log view just "bzr log --line" in that in only includes
f1, f2, the merge commit, f3, and f4. You can even drop the merge if
it's uninteresting:

	git log --no-merges mainline..featureA

The mainline..featureA syntax literally just means:

	the set of commits that are reachable by featureA
	and excluding the set of commits reachable by mainline

It's an extraordinarily powerful thing to say, and its exactly what
you want here. And it's more than a "show mainline" thing, since
theses sets of commits can consist of arbitrarily complex DAG
subsets. This syntax is just a really useful way to slice up the DAG.

And this syntax is almost universally accepted by git commands. so you
can visualize a chunk of the DAG with:

	gitk mainline..featureA

Or export it as patches with:

	git format-patch mainline..featureA

I haven't been able to find something similar in bzr yet. Does it

> If I understand it correctly, in git, you don't really know what has
> been committed as part of this branch/repo, and what has been
> committed in another branch/repo (this is my understanding from
> reading this thread, I might be wrong, feel free to correct me again
> :) )

You're correct that git doesn't _store_ any sort of "branch ownership"
in the commit object. But this is a huge feature. It avoids a lot of
the things in bzr that look so bizarre to people coming from git.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : 

More information about the bazaar mailing list