Re: VCS comparison table

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 19 Oct 2006 15:44:34 +0200, Matthieu Moy wrote:
> > The lack of parents ordering in Git is directly connected with
> > fast-forwarding.

Yes. We're identifying the core underlying technical difference behind
the recent discussion. Namely bzr treats one parent as special, (the
parent that was the branch tip previously). And this special treatment
eliminates the ability to fast-forward, adds merge commits that
wouldn't exist with fast forwarding, and is able to make its revision
numbers a bit more stable as a consequence.

> >    a       a
> >   / \     / \
> >  c   b   c   b
> >   \ /     \ /
> >    m       m
>
> Yes, bzr has similar thing too. AIUI, the difference is that git does
> it automatically, while bzr has two commands in its UI, "merge" and
> "pull".

There's a bit more to it than that though. The git command named
"pull" will perform a fast-forward if possible, but will create a
merge commit if necessary. For example:

	a       a                      a
	| pulls | and fast-forwards to |
	b       b                      b
	        |                      |
	        c                      c

whereas:

	a       a                       a
	| pulls | and creates a merge  / \
	b       c                     b   c
                                       \ /
                                        m

So I'm curious. What does bzr pull do in the case of divergence like
this? (And this is the "numbers will be changed" case, by the way).

> In your case, the "leftmost ancestor" of m is b, because at the time
> it was created, it was commited from b.

It should be mentioned that git can, (annoyingly not by default), save
a file detailing the history of a branch, (time a revision ID for
every time the branch tip moved). This is the "reflog" support and
provides the same information that bzr is encoding in its "leftmost
ancestor" branches.

Importantly, though, git's reflog is entirely local and is not
propagated by push/pull etc.

> One problem with that approach is that from revision m and looking
> backward in history (say, running "bzr log"), you have two ways to go
> backward:
>
> 1) Take the history of _your_ commits, and your pull till the point
>    where you've branched.
>
> 2) Follow the history taking the leftmost ancestor at each step.

Uhm, don't you really have to follow both? And the only ambiguity is
which one you see first?

>              In your scenario, repo1 would get a revision history of
> "a c m" while repo2 would have had "a b m" with the same tip.

OK. With git the two reflogs on the two machines would also have "a c
m" and "a b m". But is this the only kind of log that exists? If I
had code history as above and wanted to ask questions about what led
to commit m, then I would want to know about both b and c which
contribute to it.

And that's what "git log" provides. It lists all the commits that are
reachable from a given commit by following parent links. Surely bzr
has a way to view the complete history that way?

Meanwhile, I suggest that there really is no significance to which
parent of a commit used to have the branch head pointing at it. Saving
that information as part of the history is saving it in the wrong
place. It forces the user to have to be careful about which direction
merges happen, leading to awkward command sequences as demonstrated
above, (or daemons to hide them). And in the end, it's just not
important information to have saved in the permanent history.

It is useful in a transient sense to be able to say, (as git reflog
allows), what was my "master" branch pointing at yesterday, (because I
know the code was working before I merged in some bad code this
morning, for instance). But that's a local-only question and will
never have historical significance. "What was cworth's master branch
pointing at on 2006-10-18" is a question that nobody will ever need
the answer to in any historical sense.

-Carl

PS. Here are the commands the show the divergent pull example I gave
above with git:

# Start a new empty repository
$ mkdir git-example; cd git-example
$ git init-db
defaulting to local storage area

# Create initial commit 'a'
$ touch a; git add a; git commit -m "Initial commit of a"
Committing initial tree 496d6428b9cf92981dc9495211e6e1120fb6f2ba

# Create the 'b' commit on a new 'b' branch from 'a'
$ git checkout -b b; touch b; git add b; git commit -m "Add b on branch b"

# Create the 'c' commit on a new 'c' branch from 'a'
$ git checkout -b c master; touch c; git add c; git commit -m "Add c on branch c"

# Checkout the 'master' branch, (which is pointing at 'a')
$ git git checkout master

# Merge the 'b' branch, (notice that this is a fast forward)
$ git pull . b
Updating from faf5f2f7363ef5de740193afd89bedee095ef966 to 141811d050aa7008f19867280c41405e05b3dbf7
Fast forward
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 b

# Now merge the 'c' branch (notice that this is not a fast
# forward, but instead creates a new merge commit)
$ git pull . c
Trying really trivial in-index merge...
Wonderful.
In-index merge
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 c

# Show the log of commits reachable from 'master', (all 4 commits)
$ git log
commit 59b3cdaf930824d4c0def4ba7ef9b913fcf05d96
Merge: 141811d... dfc35d5...
Author: Carl Worth <cworth@xxxxxxxxxxxxxxx>
Date:   Thu Oct 19 08:15:23 2006 -0700

    Merge branch 'c'

commit dfc35d5bd88b22f836bd6f46991169d3c3960b69
Author: Carl Worth <cworth@xxxxxxxxxxxxxxx>
Date:   Thu Oct 19 08:14:30 2006 -0700

    Add c on branch c

commit 141811d050aa7008f19867280c41405e05b3dbf7
Author: Carl Worth <cworth@xxxxxxxxxxxxxxx>
Date:   Thu Oct 19 08:14:10 2006 -0700

    Add b on branch b

commit faf5f2f7363ef5de740193afd89bedee095ef966
Author: Carl Worth <cworth@xxxxxxxxxxxxxxx>
Date:   Thu Oct 19 08:13:53 2006 -0700

    Initial commit of a

Attachment: pgpOAYXsowyNJ.pgp
Description: PGP signature


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]