Git development
 help / color / mirror / Atom feed
* Re: VCS comparison table
From: Petr Baudis @ 2006-10-19 11:46 UTC (permalink / raw)
  To: Karl Hasselström
  Cc: Matthew D. Fuller, Carl Worth, Aaron Bentley, Linus Torvalds,
	Andreas Ericsson, bazaar-ng, git, Jakub Narebski
In-Reply-To: <20061019112759.GA31066@diana.vm.bytemark.co.uk>

Dear diary, on Thu, Oct 19, 2006 at 01:27:59PM CEST, I got a letter
where Karl Hasselström <kha@treskal.com> said that...
> Really, every commit. Not even the initial commit of a project is
> special -- it's just a commit with an empty parent set. And, it's
> perfectly possible to make a (merge) commit whose parents belong to
> previously disconnected parts of the DAG. This of course means that
> it's not even possible to differentiate commits based on which project
> they're part of, since one can create a commit whose parents belong to
> different projects.

FWIW, IIRC the Git project has about 6 initial commits. :-)

BTW, a popular source of horrification in other VCSes are Git's octopus
merges. (A popular source of horrification in Git are kernel developers
doing octopus merges of 40 branches at once.) Does Bazaar support those?
(I can't really say it's a defect if it doesn't...)

(An octopus merge is a merge of more than two branches at once, in a
single commit.)

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1
lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)

^ permalink raw reply

* Re: VCS comparison table
From: Matthieu Moy @ 2006-10-19 12:04 UTC (permalink / raw)
  To: Andreas Ericsson
  Cc: Matthew D. Fuller, bazaar-ng, Linus Torvalds, Carl Worth, git,
	Jakub Narebski
In-Reply-To: <45375E56.4090106@op5.se>

Andreas Ericsson <ae@op5.se> writes:

> You, and others, keep saying "leftmost". What on earth does left or
> right have to do with anything? Or rather, how do you determine which
> side anything at all is on?

Not sure it's the same in git, but in bzr, a new revision is always
created by a commit (it can be "fetched" by other commands though). If
you "merge", then you have to commit after.

What people call "leftmost ancestor" is the revision which used to be
the tip at the time you commited. For example, if you do "bzr diff;
bzr commit" the diff shown before is the same as the one got with
"bzr diff -r last:1" right after the commit.

I believe this doesn't make a difference for merge algorithms, but in
the UI, it's here when you say, e.g.:

bzr diff -r last:12..before:revid:foo@bar-auents987aue

(once in "last:", and once in "before:")

-- 
Matthieu

^ permalink raw reply

* Re: VCS comparison table
From: Petr Baudis @ 2006-10-19 12:33 UTC (permalink / raw)
  To: Matthieu Moy
  Cc: Andreas Ericsson, Matthew D. Fuller, bazaar-ng, Linus Torvalds,
	Carl Worth, git, Jakub Narebski
In-Reply-To: <vpqirigqzpd.fsf@ecrins.imag.fr>

Dear diary, on Thu, Oct 19, 2006 at 02:04:14PM CEST, I got a letter
where Matthieu Moy <Matthieu.Moy@imag.fr> said that...
> What people call "leftmost ancestor" is the revision which used to be
> the tip at the time you commited. For example, if you do "bzr diff;
> bzr commit" the diff shown before is the same as the one got with
> "bzr diff -r last:1" right after the commit.

The lack of parents ordering in Git is directly connected with
fast-forwarding.

Consider

 repo1   repo2

   a       a
  /       /
 b       c

Now repo2 merges with repo1:

 repo1   repo2

   a       a
  /       / \
 b       c   b
          \ /
           m

repo1 tip ('b') is not ancestor of repo2 tip ('c') so a three-way merge
is done and a new 'm' merge commit is created.

And now repo1 merges with repo2:

 repo1   repo2

   a       a
  / \     / \
 c   b   c   b
  \ /     \ /
   m       m

Because previous repo1 tip ('b') was ancestor of repo2 tip ('m'), a
fast-forward happenned and repo1 tip simply moved to 'm'. But this
"flipped" the development from repo1 POV - you cannot assume anymore
that the first ("leftmost") parent is special.

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1
lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)

^ permalink raw reply

* Re: VCS comparison table
From: Matthieu Moy @ 2006-10-19 13:44 UTC (permalink / raw)
  To: Petr Baudis; +Cc: bazaar-ng, git
In-Reply-To: <20061019123349.GE20017@pasky.or.cz>

Petr Baudis <pasky@suse.cz> writes:

> The lack of parents ordering in Git is directly connected with
> fast-forwarding.

[...]

>  repo1 repo2
>
>    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".

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

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.

In bzr, the notion of "branch" corresponds to a succession of
revisions, which are explicitely stored in a file (ls
.bzr/branch/revision-history), which is what commands like "log"
follow, and what is used for revision numbering. And this sucession of
revision must obey (at most) one of the above. In the past, it was 1),
which means that "pull" (i.e. fast-forward) was only adding revisions
to a branch. 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.

Today, the revision history follows leftmost ancestor. One good
property of this is that revision history is unique for a given
revision. But the terrible drawback is that "pull" and "push" do not
/add/ revisions to your revision history, they rewrite the target one
with the source one. That means I can have

$ bzr log --line
1: some upstream stuff
2: started my work
3: continued my work

# upstream merges.

$ bzr pull
$ bzr log --line
1: some upstream stuff
2: some other upstream stuff ...
3: ... commited while I was working
4: merged from Matthieu this terrible feature

-- 
Matthieu -- definitely curious to give a real try to git ;-)

^ permalink raw reply

* Re: [PATCH] reduce delta head inflated size
From: Morten Welinder @ 2006-10-19 13:49 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0610181541280.1971@xanadu.home>

On 10/18/06, Nicolas Pitre <nico@cam.org> wrote:
> Supposing that both the base and result sizes were both full size 64-bit
> values, their encoding would occupy only 9.2 bytes each.  Therefore
> inflating 64 bytes is way overkill.  Limit it to 20 bytes instead which
> should be plenty enough for a couple years to come.

2^63 ~ 9.2e18

Thus one signed 64-bit number can take up 1 sign + 19 digits + 1 nul.
That's 21 bytes.

If you don't like the constant, 4*sizeof(integer type) should work.
(Assuming sizeof measures in bytes.)

M.

^ permalink raw reply

* [PATCH 2/2] Remove dead code after direct graph drawing
From: Josef Weidendorfer @ 2006-10-19 14:13 UTC (permalink / raw)
  To: Marco Costalba; +Cc: git

Signed-off-by: Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
---

Sorry, I forgot: this is on top of your public master as of today.

Josef

 src/listview.cpp |   94 +-----------------------------------------------------
 src/listview.h   |    2 -
 2 files changed, 1 insertions(+), 95 deletions(-)

diff --git a/src/listview.cpp b/src/listview.cpp
index 418836b..84cbfe9 100644
--- a/src/listview.cpp
+++ b/src/listview.cpp
@@ -37,9 +37,6 @@ ListView::ListView(Domain* dm, Git* g, Q
 	connect(lv, SIGNAL(currentChanged(QListViewItem*)),
 	        this, SLOT(on_currentChanged(QListViewItem*)));
 
-	connect(lv, SIGNAL(contentsMoving(int,int)),
-	        this, SLOT(on_contentsMoving(int,int)));
-
 	connect(lv, SIGNAL(mouseButtonPressed(int,QListViewItem*,const QPoint&,int)),
 	        this, SLOT(on_mouseButtonPressed(int,QListViewItem*,const QPoint&,int)));
 
@@ -82,11 +79,6 @@ void ListView::setupListView() {
 
 void ListView::on_repaintListViews(QFont& f) {
 
-	QListViewItemIterator it(lv);
-	while (it.current()) {
-		it.current()->setPixmap(GRAPH_COL, NULL);
-		++it;
-	}
 	lv->setFont(f);
 	lv->ensureItemVisible(lv->currentItem());
 }
@@ -298,41 +290,6 @@ void ListView::on_contextMenuRequested(Q
 	emit contextMenu(((ListViewItem*)item)->sha(), POPUP_LIST_EV);
 }
 
-void ListView::on_contentsMoving(int, int newY) {
-// in case of very big archives pixmap memory can became huge.
-// so we free pixmap memory for not visible items, avoiding
-// traversing the list and using only the fast iterator
-// itemBelow() and NOT the slower itemAbove()
-
-	int ph = d->m()->gm.height();
-	int h = lv->visibleHeight();
-	if (lv->childCount() < h / ph + 10)
-		return;
-
-	int curY, dummy;
-	lv->viewportToContents(0, 0, dummy, curY);
-	int delta = newY - curY;
-	QListViewItem* item;
-	if (delta > 0)
-		item = lv->itemAt(QPoint(0, 0));
-	else {
-		item = lv->itemAt(QPoint(0, h + delta));
-		delta = -delta;
-		if (item)
-			item = item->itemBelow();
-	}
-	if (item == NULL)
-		return;
-
-	int cnt = 0;
-	delta /= ph;
-	while (cnt++ < delta) {
-		item->setPixmap(GRAPH_COL, NULL); // free pixmap memory
-		item = item->itemBelow();
-		if (item == NULL)
-			break;
-	}
-}
 
 bool ListView::eventFilter(QObject* obj, QEvent* ev) {
 // we need an event filter for:
@@ -463,7 +420,6 @@ void ListViewItem::paintGraph(const Rev&
     else
 	p->fillRect( 0, 0, width, height(), cg.brush( crole ) );
 	
-    // Copy from getGraph(), modified to directly draw into cell
     const QValueVector<int>& lanes(c.lanes);
     uint laneNum = lanes.count();
     int pw = pms[0]->width();
@@ -507,19 +463,11 @@ void ListViewItem::paintCell(QPainter* p
 	if (!populated)
 		setupData(c);
 
-#if 1
 	if (column == GRAPH_COL) {
 	        paintGraph(c, p, _cg, width);
 		return;
 	}
-#else
-	// pixmap graph, separated from setupData to allow deleting
-	if (!pixmap(GRAPH_COL)) {
-		QPixmap* pm = getGraph(c);
-		setPixmap(GRAPH_COL, *pm);
-		delete pm;
-	}
-#endif
+
 	// adjust for annotation id column presence
 	int mycolumn = (fh) ? column : column + 1;
 
@@ -655,46 +603,6 @@ const QString ListViewItem::timeDiff(uns
 	return tmp;
 }
 
-QPixmap* ListViewItem::getGraph(const Rev& c) {
-
-	const QValueVector<int>& lanes(c.lanes);
-	uint laneNum = lanes.count();
-	int pw = pms[0]->width();
-	int ph = pms[0]->height();
-	QPixmap* pm = new QPixmap(pw * laneNum, ph);
-	pm->fill(ODD_LINE_COL); // faster then drawRect()
-	int mergeLane = -1;
-	for (uint i = 0; i < laneNum; i++)
-		if (isMerge(lanes[i])) {
-			mergeLane = i;
-			break;
-		}
-	QPainter p;
-	p.begin(pm);
-	for (uint i = 0; i < laneNum; i++) {
-
-		int ln = lanes[i], idx;
-		if (ln == EMPTY)
-			continue;
-
-		if (ln == CROSS)
-			idx = COLORS_NUM * (NOT_ACTIVE - 1);
-		else
-			idx = COLORS_NUM * (ln - 1);
-
-		int col = (   isHead(ln) || isTail(ln) || isJoin(ln)
-		           || ln == CROSS_EMPTY) ? mergeLane : i;
-
-		idx += col % COLORS_NUM;
-		p.drawPixmap(i * pw, 0, *pms[idx]);
-		if (ln == CROSS) {
-			idx = COLORS_NUM * (CROSS - 1) + mergeLane % COLORS_NUM;
-			p.drawPixmap(i * pw, 0, *pms[idx]);
-		}
-	}
-	p.end();
-	return pm;
-}
 
 // ***************** GraphMetrics related methods *********************
 
diff --git a/src/listview.h b/src/listview.h
index 25de935..5a49512 100644
--- a/src/listview.h
+++ b/src/listview.h
@@ -34,7 +34,6 @@ public:
 private:
 	void setupData(const Rev& c);
 	void paintGraph(const Rev& c, QPainter *p, const QColorGroup &cg, int width);
-	QPixmap* getGraph(const Rev& c);
 	void addTextPixmap(SCRef text, const QColor& color, bool bold = false);
 	QPixmap* doAddTextPixmap(SCRef text, const QColor& color, int col, bool bold);
 	const QString timeDiff(unsigned long secs) const;
@@ -80,7 +79,6 @@ private slots:
 	void on_mouseButtonPressed(int, QListViewItem*, const QPoint&, int);
 	void on_clicked(QListViewItem*);
 	void on_onItem(QListViewItem*);
-	void on_contentsMoving(int, int newY);
 
 private:
 	void setupListView();
-- 
1.4.3.rc2.gf8ffb

^ permalink raw reply related

* [PATCH 1/2] Simpler way to draw commit graph
From: Josef Weidendorfer @ 2006-10-19 14:13 UTC (permalink / raw)
  To: Marco Costalba; +Cc: git

For drawing the commit graph, previously every item got a
pixmap created and set with item->setPixmap(), which is
drawn by the standard implementation of QListView::paintCell().

Instead, this commit implements drawing of the graph
directly in our own ListView::paintCell(). This gets rid of
a lot of complex code to reset the pixmap of invisible items
which was needed in large repositories before to not allocate
huge amounts of memory.

As we directly draw only the visible cells, it has no
influence on performance (especially, as we got rid of
pixmaps of invisible items before, and most often had
to draw the graph anyway).

Signed-off-by: Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
---

Hi Marco,

currently, when drawing branch/tag labels in the commit graph,
QGit shows in the graph small white spaces. This is because
these lines are a little higher than the rest, and the
pregenerated graph pixmaps only have a given height.

In order to solve this, I looked at the code, and do not understand
one thing: Why are you creating pixmaps for the graph, and do
draw directly in paintCell() ?

This patch does exactly this, and the next one does cleanup
of code which is not used afterwards.

If you like, I can comeup with a patch to directly draw the lines
which would get rid of the original problem.

Josef

 src/listview.cpp |   57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/listview.h   |    1 +
 2 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/src/listview.cpp b/src/listview.cpp
index cef1c2a..418836b 100644
--- a/src/listview.cpp
+++ b/src/listview.cpp
@@ -448,6 +448,56 @@ void ListViewItem::setDiffTarget(bool b)
 	repaint();
 }
 
+void ListViewItem::paintGraph(const Rev& c, QPainter *p, const QColorGroup &cg, int width)
+{
+    // Copied from QListViewItem::paintCell
+    QListView *lv = listView();
+    if ( !lv ) return;
+
+    const BackgroundMode bgmode = lv->viewport()->backgroundMode();
+    const QColorGroup::ColorRole crole
+	= QPalette::backgroundRoleFromMode( bgmode );
+    
+    if ( isSelected() && lv->allColumnsShowFocus() )
+	p->fillRect( 0, 0, width, height(), cg.brush( QColorGroup::Highlight ) );
+    else
+	p->fillRect( 0, 0, width, height(), cg.brush( crole ) );
+	
+    // Copy from getGraph(), modified to directly draw into cell
+    const QValueVector<int>& lanes(c.lanes);
+    uint laneNum = lanes.count();
+    int pw = pms[0]->width();
+    int mergeLane = -1;
+    for (uint i = 0; i < laneNum; i++)
+	if (isMerge(lanes[i])) {
+	    mergeLane = i;
+	    break;
+	}
+
+    for (uint i = 0; i < laneNum; i++) {
+	
+	int ln = lanes[i], idx;
+	if (ln == EMPTY)
+	    continue;
+	
+	if (ln == CROSS)
+	    idx = COLORS_NUM * (NOT_ACTIVE - 1);
+	else
+	    idx = COLORS_NUM * (ln - 1);
+	
+	int col = (   isHead(ln) || isTail(ln) || isJoin(ln)
+		      || ln == CROSS_EMPTY) ? mergeLane : i;
+	
+	idx += col % COLORS_NUM;
+	p->drawPixmap(i * pw, 0, *pms[idx]);
+	if (ln == CROSS) {
+	    idx = COLORS_NUM * (CROSS - 1) + mergeLane % COLORS_NUM;
+	    p->drawPixmap(i * pw, 0, *pms[idx]);
+	}
+    }
+}
+
+
 void ListViewItem::paintCell(QPainter* p, const QColorGroup& cg,
                              int column, int width, int alignment) {
 	QColorGroup _cg(cg);
@@ -457,12 +507,19 @@ void ListViewItem::paintCell(QPainter* p
 	if (!populated)
 		setupData(c);
 
+#if 1
+	if (column == GRAPH_COL) {
+	        paintGraph(c, p, _cg, width);
+		return;
+	}
+#else
 	// pixmap graph, separated from setupData to allow deleting
 	if (!pixmap(GRAPH_COL)) {
 		QPixmap* pm = getGraph(c);
 		setPixmap(GRAPH_COL, *pm);
 		delete pm;
 	}
+#endif
 	// adjust for annotation id column presence
 	int mycolumn = (fh) ? column : column + 1;
 
diff --git a/src/listview.h b/src/listview.h
index 672ed7d..25de935 100644
--- a/src/listview.h
+++ b/src/listview.h
@@ -33,6 +33,7 @@ public:
 
 private:
 	void setupData(const Rev& c);
+	void paintGraph(const Rev& c, QPainter *p, const QColorGroup &cg, int width);
 	QPixmap* getGraph(const Rev& c);
 	void addTextPixmap(SCRef text, const QColor& color, bool bold = false);
 	QPixmap* doAddTextPixmap(SCRef text, const QColor& color, int col, bool bold);
-- 
1.4.3.rc2.gf8ffb

^ permalink raw reply related

* Re: [PATCH] reduce delta head inflated size
From: Nicolas Pitre @ 2006-10-19 14:17 UTC (permalink / raw)
  To: Morten Welinder; +Cc: Junio C Hamano, git
In-Reply-To: <118833cc0610190649o484afdc8lb871d4b3c5361166@mail.gmail.com>

On Thu, 19 Oct 2006, Morten Welinder wrote:

> On 10/18/06, Nicolas Pitre <nico@cam.org> wrote:
> > Supposing that both the base and result sizes were both full size 64-bit
> > values, their encoding would occupy only 9.2 bytes each.  Therefore
> > inflating 64 bytes is way overkill.  Limit it to 20 bytes instead which
> > should be plenty enough for a couple years to come.
> 
> 2^63 ~ 9.2e18
> 
> Thus one signed 64-bit number can take up 1 sign + 19 digits + 1 nul.
> That's 21 bytes.

No.  In this case the value is kept binary, with bits spread over 
consecutive bytes but with the MSB indicating continuation on the next 
byte.

This means 64 bits / 7 bits per byte = 9.1 bytes, hence 10.  Then there 
are 2 of those values that makes 20 bytes.


Nicolas

^ permalink raw reply

* Re: [ANNOUNCE] Example Cogito Addon - cogito-bundle
From: Nicolas Pitre @ 2006-10-19 14:27 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Linus Torvalds, git
In-Reply-To: <7vac3tx900.fsf@assigned-by-dhcp.cox.net>

On Wed, 18 Oct 2006, Junio C Hamano wrote:

> Linus Torvalds <torvalds@osdl.org> writes:
> 
> > Actually, I've hit an impasse.
> >
> > So there's _another_ way of fixing a thin pack: it's to expand the objects 
> > without a base into non-delta objects, and keeping the number of objects 
> > in the pack the same. But _again_, we don't actually know which ones to 
> > expand until it's too late.
> 
> pack-objects.c::write_one() makes sure that we write out base
> immediately after delta if we haven't written out its base yet,
> so I suspect if you buffer one delta you should be Ok, no?

If we create full packs out of thin packs the base objects will end up 
at the end of the pack so this assumption is a bad one to rely upon if 
we want to make things robust (like being able to feed such a pack 
back).


Nicolas

^ permalink raw reply

* Re: [ANNOUNCE] Example Cogito Addon - cogito-bundle
From: Linus Torvalds @ 2006-10-19 14:55 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vac3tx900.fsf@assigned-by-dhcp.cox.net>



On Wed, 18 Oct 2006, Junio C Hamano wrote:
>
> Linus Torvalds <torvalds@osdl.org> writes:
> >
> > Actually, I've hit an impasse.
> >
> > So there's _another_ way of fixing a thin pack: it's to expand the objects 
> > without a base into non-delta objects, and keeping the number of objects 
> > in the pack the same. But _again_, we don't actually know which ones to 
> > expand until it's too late.
> 
> pack-objects.c::write_one() makes sure that we write out base
> immediately after delta if we haven't written out its base yet,
> so I suspect if you buffer one delta you should be Ok, no?

It doesn't matter. I realized that my bogus patch to unpack-objects was 
more seriously broken anyway: even the "un-deltify every single object" 
was broken. And that's despite the fact that I _tested_ it, and verified 
the end result by hand.

Why? Because I tested it within one repo, by just piping the output of 
git-pack-objects --stdout directly to the repacker. That seemed to be a 
good way to test it without setting up anything bigger. But it turns out 
that it misses one of the big problems: if you don't unpack the objects in 
a way that later phases can read, none of the streaming code works at all, 
and you have to buffer up _everything_ in memory just to be able to read 
any previous _non_delta objects too.

So my patch-series works - but it only works in a repo that already has 
all the objects in question, because then it can look up the objects in 
the original database. Which makes it useless. Duh.

So forget about unpack-objects. It's designed to be streaming (and it's a 
_good_ design for what it does), but repacking really cannot be done that 
way. Repacking needs to be done by saving the thin pack to disk, and then 
doing a multi-pass over it (like git-index-pack does, for example).

Just throw my patch away. It's not even useful as a basis for anything 
else, unless you want to use it as a way to keep all the objects in memory 
and use the "unpack-objects" logic to just _parse_ the incoming pack.

I suspect using "index-pack" is saner (since it already has the multi-pass 
logic), or just doing somethign that maps all the objects in memory, and 
then calls builtin-pack-objects once it has set up the new thin pack so 
that others can see/use the new objects without realizing that they aren't 
in the canonical pack-format.

		Linus

^ permalink raw reply

* Re: VCS comparison table
From: Tim Webster @ 2006-10-19 14:57 UTC (permalink / raw)
  To: Matthieu Moy; +Cc: Andreas Ericsson, Christian MICHON, bazaar-ng, git
In-Reply-To: <vpqwt6wsmb5.fsf@ecrins.imag.fr>

On 10/19/06, Matthieu Moy <Matthieu.Moy@imag.fr> wrote:
> Andreas Ericsson <ae@op5.se> writes:
>
> > Perhaps not, but the tone is friendly (mostly), the patience of the
> > bazaar people seems infinite and lots of people seem to be having fun
> > while at the same time learning a thing or two about a different SCM.
> > Best case scenario, both git and bazaar come out of the discussion as
> > better tools. If there would never be any cross-pollination, git
> > wouldn't have half the features it has today.
>
>


Thanks everyone for taking time to explain details.

However, I don't use SCM for code development. I use it for collaborative
documentation, white boarding and tracking configurations.
In fact in my company no one uses SCM for code development.
Everyone here uses it for collaborative documentation and white boarding.
Only I use SCM for tracking configurations.

I think of SCMs in terms of an SCM core and SCM tools.

First I want to say every SCM I know of sucks when it comes to tracking
configurations, simply because they don't record or restore file metadata,
like perms, ownership, and acl. I don't see recording or restoring
file metadata as part of the SCM core. I do however feel an SCM core needs to
have provisions for extended file inventory information. The problem
with extended file inventory information, it is fs specific. For this reason I
feel it is essential that the SCM core allow multiple sets of extended file
inventory information. The SCM tools are responsible, based on the local
config, for recording metadata and creating extended file inventory,
translating file metadata of one file system. When tracking configurations
octopus merges are surprisingly common. If a configuration changed is
not signed off by a responsible person, it can not be accepted. Doing
otherwise is simply an invitation to attackers and makes trouble shooting
far too difficult. Also configuration file in one directory will most often not
be members of the same repo. For example each file etc in directory would
members of different repos according to its associated application/pkg.

Somethings I like the SCM tools to handle. Personally I would like the
SCM tools to be platform independent. This would ensure that correct
things happening on ext3 mounted on windows.
I don't think execute bit belongs in the basic file inventory information.
Instead I would like to use this replace by a filter in the extended
file inventory
indicating what file metadata if any should be recorded or restored.
When the local SCM tools config has use metadata enable, the filter is used.
A filter lets the user select file metadata to record/restore such as;
record ownership, record permissions, record acl.

For SCM configuration tracking to function reliably, pulls, pushes and merges
need to be atomic. Personally I like my servers to pull change updates. And
I like to push changes I make on local servers to branches. On configuration
master merge the  branches into groups. When the server pulls changes
for a particular application/pkg, the following is a list of steps that need to
occur.
The SCM tools, perform a pre update step, such as optionally stopping a service
pull updates and build changes files in a scratch space, than apply
file metadata,
unchanged files would be links from the scratch space to the original files,
verify all files are correct by checking their sha1 or md5,
atomically move configuration files and scripts to install them,
perform a post update step,  such as starting or reloading a service.
The pre update step and the post update are very much like pkg pre and post
install scripts. The pre update and post update scripts are in fact part of the
application/pkg configurations files.


Collaborative document editing and white boarding are other requirements.
odf and svg are xml file formats. I would like to see an efficient
xml diff as part of the SCM core. Using mime types SCM tools can unzip
files, bundles, and use mime type information to the SCM core xml
diff, plain diff
as required. I think it is essential that the SCM core include
previsions for multiple
repo partners. For example this can be used to create fail over star
scm architecture.
In collaborative document editing it is often the case where you want to
compress / summarize some of the change history.

We currently use our scm based collaborative document editing as an ad
hock white
board, coordinating our commits and updates via IM. :)
It would be nice if the SCM tools included rss feeds for communicating zip
patch bundles.

^ permalink raw reply

* Re: VCS comparison table
From: Aaron Bentley @ 2006-10-19 14:58 UTC (permalink / raw)
  To: Carl Worth
  Cc: Linus Torvalds, Jakub Narebski, Andreas Ericsson, bazaar-ng, git
In-Reply-To: <87lkncev90.wl%cworth@cworth.org>

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Carl Worth wrote:
> On Wed, 18 Oct 2006 23:10:11 -0400, Aaron Bentley wrote:
> But think about your favorite example of an unhealthy social situation
> around a software project and a big, nasty fork. Every example I can
> think of involves some technical distinction that makes one branch
> more special than another.
>
> Now, those situations also involve social problems, and those are even
> more significant. But the technical blessing of one branch does not
> help. And I think it contributes to the social problems in many cases.

I'm not as familiar with those details.  The one fork that I know a lot
about, when Baz (the old Bazaar architecture) forked off from Arch,
showed me that for each developer branch, one branch must be special.

This is just because it is hard to maintain a branch that applies
cleanly to two diverging codebases.  So each developer must develop
against the fork that they want to merge their code into.  If they want
their code to be applied to the other fork, someone must port it.

So I really do feel that special branches are inescapable.

With bzr, you have the freedom to choose which branch you consider
special, and change your mind at any time.  There are no technical
limitations in that regard.

> As far as the revision numbers, my impression is that the numbers
> would be confusing or worthless if I were to use bzr the way I'm
> currently using git, as they certainly could not remain stable.

They would remain stable if you only used pull to update your origin
branch, and used merge+commit to update your development branch.

>> In bzr development, it's very rare for anyone's revision numbers to change.
> 
> Which just says to me that the bzr developers really are sticking to a
> centralized model.

I don't see why you're reaching that conclusion.  I'd like to understand
that better, because Linus seems to be concluding the same thing, and it
doesn't make sense to me.

>> I think you're implying that on a technical level, bzr doesn't support
>> this.  But it does.  Every published repository has unique identifiers
>> for every revision on its mainline, and it's exceedingly uncommon for
>> these to change.
> 
> Every argument you make for the number change being uncommon just
> strengthens the argument that it will be all that more
> confusing/frustrating when the numbers do change.

That doesn't follow.  Just because something is arguably true doesn't
make it bad.  And in this case, I'm not arguing that it's true, I'm
saying that it's true, because that is what my experience tells me is true.

> In cairo, for example, we've made a habit of including a revision
> identifier in our bug tracking system for every commit that resolves a
> bug.

We do it the other way around: we put a bug number in the commit
message.  And I personally have been developing a bugtracker that is
distributed in the same way bzr is; it stores bug data in the source
tree of a project, so that bug activities follow branches around.

> I like having the assurance that those numbers will survive
> forever. And it doesn't matter if the repository moves, or the project
> is forked, or anything else. Those numbers cannot change.
> 
> I understand that bzr also has unique identifiers, but it sounds like
> the tools try to hide them, and people aren't in the habit of using
> them for things like this. Do bzr developers put revision numbers in
> their bug trackers? Is there a guarantee they will always be valid?

Yes, we put revnos in our bug trackers.  No, we can't prove that they
will always be valid.  But there are significant disincentives to
changing them, so I am quite comfortable assuming they will not change.
 And the older a revno gets, the less likely it is to change.

On the other hand, I think your revision identifiers are not as
permanent as you think.

In the first place, it seems fairly common in the Git community to
rebase.  This process throws away old revisions and creates new
revisions that are morally equivalent[1].  I don't know whether Git
fetches unreferenced revisions, but bzr's policy is to fetch only
revisions referenced in the ancestry DAG of the branch.

In the second place, one must consider the "nuclear launch codes"
scenario.  In this scenario, someone has committed the codes necessary
to begin a nuclear attack into their branch.  This is an unlikely event,
of course, but nuclear launch codes are an extreme example of data that
absolutely, positively must be completely expunged from the branch.
Other examples include proprietary code (e.g. if SCO wasn't a bunch of
charlatans), passwords and obscene or libelous statements.

In a nuclear codes scenario, the revision that introduced the nuclear
launch codes and all its descendants must be expunged from the
repository.  You may, perhaps, rebase in order to retain the shape of
the history, but the revision-ids that you have recorded will be gone.

Aaron

[1] This is a process that I find discomforting, because I consider the
original revisions to be real, historical data, and I don't like the
idea of throwing it away.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFFN5F70F+nu1YWqI0RAhrsAJ9rcqNGv28134eTvbGoxxteOxif3wCfTbaq
fpD0HNeGgdlMwuJldyzUxRM=
=9k8r
-----END PGP SIGNATURE-----

^ permalink raw reply

* Re: VCS comparison table
From: Matthew D. Fuller @ 2006-10-19 15:17 UTC (permalink / raw)
  To: Petr Baudis; +Cc: Erik B?gfors, bazaar-ng, git
In-Reply-To: <20061019113731.GC20017@pasky.or.cz>

[ trim back CC a bit ]

On Thu, Oct 19, 2006 at 01:37:31PM +0200 I heard the voice of
Petr Baudis, and lo! it spake thus:
> 
> [...] you probably primarily show revnos everywhere and UUIDs only
> in few special places and/or when asked specifically through a
> command (correct me if I'm wrong).

The primary place you'd see either is in 'log'.  To show the UUID,
you'd add a "--show-ids" arg to it (and via per-user config aliasing,
you could just alias 'log' to 'log --show-ids' if you always wanted to
see them, so you wouldn't have to type it.  The output looks something
like:

revno: 1
revision-id: fullermd@over-yonder.net-20061019151437-5b99dff6ed1d76cd
committer: Matthew Fuller <fullermd@over-yonder.net>
branch nick: a
timestamp: Thu 2006-10-19 10:14:37 -0500
message:
  Foo

(without --show-ids, it's the same, except not showing the
revision-id: line)


> Also, do you support "UUID autocompletion" so that you can type just
> the unique UUID prefix instead of the whole thing?

With the form of bzr UUID's, that's not particularly useful, since
you're probably into the minutes/seconds of the timestamp before it
becomes unique, at which points you're close to 2/3 of the way through
the whole string.



-- 
Matthew Fuller     (MF4839)   |  fullermd@over-yonder.net
Systems/Network Administrator |  http://www.over-yonder.net/~fullermd/
           On the Internet, nobody can hear you scream.

^ permalink raw reply

* Re: VCS comparison table
From: Linus Torvalds @ 2006-10-19 15:25 UTC (permalink / raw)
  To: Carl Worth
  Cc: Aaron Bentley, Jakub Narebski, Andreas Ericsson, bazaar-ng, git
In-Reply-To: <87lkncev90.wl%cworth@cworth.org>



On Wed, 18 Oct 2006, Carl Worth wrote:
> 
> I understand that bzr also has unique identifiers, but it sounds like
> the tools try to hide them, and people aren't in the habit of using
> them for things like this. Do bzr developers put revision numbers in
> their bug trackers? Is there a guarantee they will always be valid?

bzr seems to use the classic UUID format, and it's funny how much it looks 
like a real BK ChangeSet revision number ("key").

Here's the quoted bzr "true" revision ID:

	Matthieu.Moy@imag.fr-20061017152029-4c5a2861bcf23b7d

and here's a BK "ChangeSet Key":

	adi@zaphod.bitmover.com|ChangeSet|20031031183805|57296

(I don't have BK installed anywhere, so I had to google for changeset 
keys, and this was just some random key in the BK bugzilla ;)

Looks very similar, don't they? And yes, the true revision ID is stable 
over time (at least it was in BK, and I assume it is in bzr too).

The biggest difference seems to be that in bzr, the final checksum is 
64-bit, while for BK, it was just a 16-bit checksum/unique number (the 
rest is just user-name/machine-name and date: I assume that the bzr commit 
was done at 10/17/2006 3:20:29PM, and the example BK ChangeSet was created 
10/31/2003 6:38:50PM - it looks like _exactly_ the same date format).

With BK, you can also use a "md5 key", and I don't actually know how they 
work. They may just be the md5 hash of the ChangeSet key, I think that may 
be how those things are indexed. So in bkcvs, you'll see a line like this:

	BKrev: 42516681VmgTWL0bkLcltPGiI6Yk5Q

which is the BK md5 key for my last kernel revision in BK (2.6.12-rc2). 
Again, these numbers are stable, unlike the simple revisions.

Note that from a usability standpoint, the UUID's look more readable to a 
human, but are actually much worse than the md5 keys (or the SHA1's that 
git uses). At least with a hash, the first few digits are likely to be 
unique, so you can do things like auto-completion (or just short names). 
With the email+date+random number kind of UUID, you don't have that.

(Pure hashes obviously also tend to just all have the same length, and are 
easier to parse automatically, so from a programmatic standpoint they are 
a lot easier too - but the surprising thing is how they are actually 
easier on humans too, even if the UUID's look more readable).

			Linus

^ permalink raw reply

* Re: VCS comparison table
From: Aaron Bentley @ 2006-10-19 15:30 UTC (permalink / raw)
  To: Tim Webster
  Cc: Matthieu Moy, Christian MICHON, Andreas Ericsson, bazaar-ng, git
In-Reply-To: <72877ab10610190757u3d2b4df0o204c6ffd73af69b4@mail.gmail.com>

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Tim Webster wrote:
> First I want to say every SCM I know of sucks when it comes to tracking
> configurations, simply because they don't record or restore file metadata,
> like perms, ownership, and acl.

Arch supports that kind of metadata.

I believe SVN supports recording arbitrary file properties, so it's just
a matter of applying those properties to the tree.

> Somethings I like the SCM tools to handle. Personally I would like the
> SCM tools to be platform independent. This would ensure that correct
> things happening on ext3 mounted on windows.
> I don't think execute bit belongs in the basic file inventory information.

Our choices have been predicated on producing the best SCM we can for
the purpose of developing software.  We find that the execute bit is
very useful for build scripts and other incidental scripts.

The other attributes didn't seem useful for software development, so
they're not part of the baseline.

> Collaborative document editing and white boarding are other requirements.
> odf and svg are xml file formats. I would like to see an efficient
> xml diff as part of the SCM core. Using mime types SCM tools can unzip
> files, bundles, and use mime type information to the SCM core xml
> diff, plain diff
> as required.

An XML diff/patch or merge will not handle ODF properly.  There's too
much extra semantic information.

> I think it is essential that the SCM core include
> previsions for multiple
> repo partners.

You mean multiple merge sources?

> It would be nice if the SCM tools included rss feeds for communicating zip
> patch bundles.

The bzr "webserve" plugin provides rss feeds.

Aaron
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFFN5oB0F+nu1YWqI0RAjSoAJ9xrZtSrZpVVoz6qAf/sZnd/StsUACfenqX
6bemNgMSbhtL0JjIlvulrb4=
=bSpK
-----END PGP SIGNATURE-----

^ permalink raw reply

* Re: VCS comparison table
From: Ramon Diaz-Uriarte @ 2006-10-19 15:45 UTC (permalink / raw)
  To: Andreas Ericsson; +Cc: Christian MICHON, bazaar-ng, git
In-Reply-To: <45373E27.3050209@op5.se>

On 10/19/06, Andreas Ericsson <ae@op5.se> wrote:
> Christian MICHON wrote:
> > close to 200 post on bzr-git war!
> > is this the right place (git mailing list) to discuss about future
> > features of bzr ?
> >
>
> Perhaps not, but the tone is friendly (mostly), the patience of the
> bazaar people seems infinite and lots of people seem to be having fun
> while at the same time learning a thing or two about a different SCM.
> Best case scenario, both git and bazaar come out of the discussion as
> better tools. If there would never be any cross-pollination, git
> wouldn't have half the features it has today.
>

I fully agree with Andreas: I am just a bzr user (not even a bzr
developer) and when looking for a decentralized VCS I also looked at
git and a few others. I think I am learning quite a bit  about bzr,
git, and VCS in general.

R.

> --
> Andreas Ericsson                   andreas.ericsson@op5.se
> OP5 AB                             www.op5.se
> Tel: +46 8-230225                  Fax: +46 8-230231
>
>


-- 
Ramon Diaz-Uriarte
Statistical Computing Team
Structural Biology and Biocomputing Programme
Spanish National Cancer Centre (CNIO)
http://ligarto.org/rdiaz

^ permalink raw reply

* "stage files" vs "cached files"
From: Jerome Lovy @ 2006-10-19 13:45 UTC (permalink / raw)
  To: git

Hi,

after having read tutorial1+2, I thought the following were more or less 
synonyms: index ~ directory cache ~ staging area

But then I discover that --cache and --staged are two different things, 
notably when using ls-files.

The documentation states indeed:
  "--cached   Show cached files in the output"
  "--stage    Show stage files in the output"

I'm a bit confused. Is maybe a "stage file" entry missing in the glossary?

TIA for clarification/pointer.
Jérôme

^ permalink raw reply

* Re: "stage files" vs "cached files"
From: Linus Torvalds @ 2006-10-19 15:58 UTC (permalink / raw)
  To: Jerome Lovy; +Cc: Git Mailing List
In-Reply-To: <eh7vl2$unr$1@sea.gmane.org>



On Thu, 19 Oct 2006, Jerome Lovy wrote:
> 
> after having read tutorial1+2, I thought the following were more or less
> synonyms: index ~ directory cache ~ staging area
> 
> But then I discover that --cache and --staged are two different things,
> notably when using ls-files.
> 
> The documentation states indeed:
>  "--cached   Show cached files in the output"
>  "--stage    Show stage files in the output"

That is indeed confusing.

It shouldn't be "stage files". It should be "file stages".

The "stage" of a file is something that is meaningful on merges. Normally 
all files are in "stage 0", which means that it's fully merged. So when 
you do

	git ls-files --stage

you'll see a listing of all the files, with their file modes, SHA1's, 
"stage" and filename. And you'll basically always see "0" in the stage 
column.

But if you have had a merge that didn't resolve automatically, you can see 
the same filename listed up to three times, with stages 1, 2 and 3 (a zero 
will never be combined with any other stage - you'll only see a zero 
alone).

That just shows how that particular file came to be: a "stage 1" entry is 
the base branch version (the "common ancestor"), while stages 2 and 3 are 
the first and second branch respectively.

> I'm a bit confused. Is maybe a "stage file" entry missing in the glossary?

That term doesn't exist, so it shouldn't be in the glossary (or in any 
man-pages). But the "merge stage" _of_ a file is a real concept.

			Linus

^ permalink raw reply

* Re: "stage files" vs "cached files"
From: Andy Whitcroft @ 2006-10-19 15:58 UTC (permalink / raw)
  To: t2a2e9z8ncbs9qg; +Cc: git
In-Reply-To: <eh7vl2$unr$1@sea.gmane.org>

Jerome Lovy wrote:
> Hi,
> 
> after having read tutorial1+2, I thought the following were more or less
> synonyms: index ~ directory cache ~ staging area
> 
> But then I discover that --cache and --staged are two different things,
> notably when using ls-files.
> 
> The documentation states indeed:
>  "--cached   Show cached files in the output"
>  "--stage    Show stage files in the output"
> 
> I'm a bit confused. Is maybe a "stage file" entry missing in the glossary?
> 
> TIA for clarification/pointer.
> Jérôme

This is not stage as in staging area, its stage as in 'at a cirtain
stage'.  It refers to files which are in the index but are in conflict.

The cache doesn't just contain an entry for each file.  It contains an
entry for each file version in a merge situation.  These are referred to
as 'stages'.  There is a description in the documentation about how they
get pushed 'down' to stage 0 and then are deemed merged (see
Documentation/core-tutorial.txt).

Below is the git ls-files --cached, and --stage output from a repo which
has one file 'bar' which is fine and another 'bar' which has a conflict.

  apw@pinky$ git ls-files --cached
  bar
  this
  this
  this
  apw@pinky$ git ls-files --stage
  100644 8dc5f23c673e9c1ac8dd3499f9acab11b093527f 0       bar
  100644 01e79c32a8c99c557f0757da7cb6d65b3414466d 1       this
  100644 fbbafbfdaadbff9c7f8db580f91a8ab5a0653704 2       this
  100644 10c8337d3d240283bdf35af68d17d1319ca069a4 3       this

Note that there is in fact three 'this's in the index.  The first entry
is bar which is in stage 0 and is merged fine.  'this' however appears
three times.  1 represents the common parent of the merge (I believe)
and 2 and 3 represent the conflicting options for that.  The 'this' on
disk has the mangled version with both sets of changes in, but this
information can be used to show the actual files in the various forms.

  apw@pinky$ git cat-file blob :1:this
  1
  2
  3
  apw@pinky$ git cat-file blob :2:this
  1
  2b
  3
  apw@pinky$ git cat-file blob :3:this
  1
  2a
  3
  apw@pinky$ cat this
  1
  <<<<<<< HEAD/this
  2b
  =======
  2a
  >>>>>>> c2acfdd8e6a50e571a007744e023c65c7b188dbf/this
  3

-apw

^ permalink raw reply

* Re: VCS comparison table
From: Matthew D. Fuller @ 2006-10-19 16:01 UTC (permalink / raw)
  To: Petr Baudis
  Cc: Karl Hasselström, bazaar-ng, Linus Torvalds, Carl Worth,
	Andreas Ericsson, git, Jakub Narebski
In-Reply-To: <20061019114639.GD20017@pasky.or.cz>

On Thu, Oct 19, 2006 at 01:46:39PM +0200 I heard the voice of
Petr Baudis, and lo! it spake thus:
> 
> Does Bazaar support those?  (I can't really say it's a defect if it
> doesn't...)

By default, merge will refuse to do its thing if there are uncommitted
changes in the working tree, whether those changes are something
you've done, or the pending results of a previous merge.  A '--force'
arg to merge will make it go forward though, so yes, you can merge
multiple other branches in one merge if you want to.

Actually, I can kill 2 birds here.  Quick little bictopus merge:

% bzr log --show-ids
------------------------------------------------------------
revno: 2
revision-id: fullermd@over-yonder.net-20061019151856-c3b406b8bcdfb537
parent: fullermd@over-yonder.net-20061019151437-5b99dff6ed1d76cd
parent: fullermd@over-yonder.net-20061019151800-2fe41e4949f5e237
parent: fullermd@over-yonder.net-20061019151807-3d7047e387edcad9
committer: Matthew Fuller <fullermd@over-yonder.net>
branch nick: a
timestamp: Thu 2006-10-19 10:18:56 -0500
message:
  merge
    ------------------------------------------------------------
    revno: 1.2.1
    merged: fullermd@over-yonder.net-20061019151800-2fe41e4949f5e237
    parent: fullermd@over-yonder.net-20061019151437-5b99dff6ed1d76cd
    committer: Matthew Fuller <fullermd@over-yonder.net>
    branch nick: b
    timestamp: Thu 2006-10-19 10:18:00 -0500
    message:
      bar
    ------------------------------------------------------------
    revno: 1.1.1
    merged: fullermd@over-yonder.net-20061019151807-3d7047e387edcad9
    parent: fullermd@over-yonder.net-20061019151437-5b99dff6ed1d76cd
    committer: Matthew Fuller <fullermd@over-yonder.net>
    committer: Matthew Fuller <fullermd@over-yonder.net>
    branch nick: c
    timestamp: Thu 2006-10-19 10:18:07 -0500
    message:
      baz
------------------------------------------------------------
revno: 1
revision-id: fullermd@over-yonder.net-20061019151437-5b99dff6ed1d76cd
committer: Matthew Fuller <fullermd@over-yonder.net>
branch nick: a
timestamp: Thu 2006-10-19 10:14:37 -0500
message:
  Foo


(I'll refer to revids by the last segment)

Note that this also shows the "left-most" parent distinction.  The
"left-most" parent of revno 2 (c3b406b8bcdfb537) is revno 1
(5b99dff6ed1d76cd), because that's the last thing I did in THIS
branch.  That's my 'mainline'; the commits from branch b
(2fe41e4949f5e237) and c (3d7047e387edcad9) are then additional
parents of the merge at revno 2.

The graph for branch a now looks something like (calling the 3
original commits 'a', 'b', and 'c' and the merge rev 'D'):

  a-.
  |\ \
  | b c
  |/ /
  D-'


The 2fe41e4949f5e237 rev is on branch b's mainline forever, and it has
a single-digit revno (2 in this case) on branch b, but it's not on
mine in a.  Now, let's pretend we're branch b, and we want to pick up
from a.  Because a is a superset of b, we could pull ('fast-forward')
a.  If we do that, the graph in b will be identical to a (and so 'log'
will be too).  That, AIUI, is what you'd do in git.

In the bzr methodology we've been discussing, where you want to
maintain your branch's identity, you'd instead merge from a into b.
You've got two new revisions to pick up in doing so; the
3d7047e387edcad9 from branch c, and the merge rev c3b406b8bcdfb537;
you already have 2fe41e4949f5e237 on your mainline.  So, post-merge,
the log for b will look like (somewhat trimmed for space):


------------------------------------------------------------
revno: 3
revision-id: fullermd@over-yonder.net-20061019153827-78d6209cd0f5f2f7
parent: fullermd@over-yonder.net-20061019151800-2fe41e4949f5e237
parent: fullermd@over-yonder.net-20061019151856-c3b406b8bcdfb537
branch nick: b
    ------------------------------------------------------------
    revno: 1.1.1
    merged: fullermd@over-yonder.net-20061019151856-c3b406b8bcdfb537
    parent: fullermd@over-yonder.net-20061019151437-5b99dff6ed1d76cd
    parent: fullermd@over-yonder.net-20061019151800-2fe41e4949f5e237
    parent: fullermd@over-yonder.net-20061019151807-3d7047e387edcad9
    branch nick: a
    ------------------------------------------------------------
    revno: 1.2.1
    merged: fullermd@over-yonder.net-20061019151807-3d7047e387edcad9
    parent: fullermd@over-yonder.net-20061019151437-5b99dff6ed1d76cd
    branch nick: c
------------------------------------------------------------
revno: 2
revision-id: fullermd@over-yonder.net-20061019151800-2fe41e4949f5e237
parent: fullermd@over-yonder.net-20061019151437-5b99dff6ed1d76cd
branch nick: b
------------------------------------------------------------
revno: 1
revision-id: fullermd@over-yonder.net-20061019151437-5b99dff6ed1d76cd
branch nick: a


The 2fe41e4949f5e237 which was originally on b's mainline is still on
the mainline at revno 2.  The graph in b now looks like (adding the
new 'E' merge commit)[0]:

  a-.
  |\ \
  b c |
  |\|/
  | D
  |/ 
  E


Now, the question of "is that merge commit E really necessary, when
you could just attach D to the end of the graph and create something
like:

  a-.
  |\ \
  b c |
  |/ /
  D-'

is perhaps a useful question (and one that there's obviously
disagreement on).  And it may be a fruitful one to discuss, if we're
not way off in the weeds already.  But, it's also not QUITE the same
question as "Is the left-vs-other path distinction meaningful and to
be preserved?"



[0] For reference at this point:
    a: 5b99dff6ed1d76cd
    b: 2fe41e4949f5e237
    c: 3d7047e387edcad9
    D: c3b406b8bcdfb537
    E: 78d6209cd0f5f2f7


-- 
Matthew Fuller     (MF4839)   |  fullermd@over-yonder.net
Systems/Network Administrator |  http://www.over-yonder.net/~fullermd/
           On the Internet, nobody can hear you scream.

^ permalink raw reply

* Re: VCS comparison table
From: Carl Worth @ 2006-10-19 16:03 UTC (permalink / raw)
  To: Matthieu Moy; +Cc: Petr Baudis, bazaar-ng, git
In-Reply-To: <vpqr6x4pghp.fsf@ecrins.imag.fr>

[-- Attachment #1: Type: text/plain, Size: 5872 bytes --]

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@raht.cworth.org>
Date:   Thu Oct 19 08:15:23 2006 -0700

    Merge branch 'c'

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

    Add c on branch c

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

    Add b on branch b

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

    Initial commit of a

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [ANNOUNCE] Example Cogito Addon - cogito-bundle
From: Jan Harkes @ 2006-10-19 16:07 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0610190747060.3962@g5.osdl.org>

On Thu, Oct 19, 2006 at 07:55:18AM -0700, Linus Torvalds wrote:
> On Wed, 18 Oct 2006, Junio C Hamano wrote:
> >
> > Linus Torvalds <torvalds@osdl.org> writes:
> > >
> > > Actually, I've hit an impasse.
> > >
> > > So there's _another_ way of fixing a thin pack: it's to expand the objects 
> > > without a base into non-delta objects, and keeping the number of objects 
> > > in the pack the same. But _again_, we don't actually know which ones to 
> > > expand until it's too late.
> > 
> > pack-objects.c::write_one() makes sure that we write out base
> > immediately after delta if we haven't written out its base yet,
> > so I suspect if you buffer one delta you should be Ok, no?
> 
> It doesn't matter. I realized that my bogus patch to unpack-objects was 
> more seriously broken anyway: even the "un-deltify every single object" 
> was broken. And that's despite the fact that I _tested_ it, and verified 
> the end result by hand.
> 
> Why? Because I tested it within one repo, by just piping the output of 
> git-pack-objects --stdout directly to the repacker. That seemed to be a 
> good way to test it without setting up anything bigger. But it turns out 
> that it misses one of the big problems: if you don't unpack the objects in 
> a way that later phases can read, none of the streaming code works at all, 
> and you have to buffer up _everything_ in memory just to be able to read 
> any previous _non_delta objects too.

You are correct that it is not possible to create a pack with all
objects expanded in a single pass. But that doesn't mean that a single
pass conversion to a full pack is impossible.

If we find a delta against a base that is not found in our repository we
can keep it as a delta, the base should show up later on in the
thin-pack. Whenever we find a delta against a base that we haven't seen
in the received part of the thin pack, but is available from the
repository we should expand it because there is a chance we may not see
this base in the remainder of the thin-pack.

> So my patch-series works - but it only works in a repo that already has 
> all the objects in question, because then it can look up the objects in 
> the original database. Which makes it useless. Duh.

About that patch series, is there a simple way to import the series into
a local repository? git-am doesn't like it, even after splitting it into
separate files on the linebreaks. I guess git-mailinfo could be taught
to recognise the git-log headers. Or have I missed some useful git apply
trick.

Jan

^ permalink raw reply

* Re: VCS comparison table
From: Matthew D. Fuller @ 2006-10-19 16:13 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Carl Worth, Andreas Ericsson, bazaar-ng, git, Jakub Narebski
In-Reply-To: <Pine.LNX.4.64.0610190757100.3962@g5.osdl.org>

On Thu, Oct 19, 2006 at 08:25:26AM -0700 I heard the voice of
Linus Torvalds, and lo! it spake thus:
> 
> The biggest difference seems to be that in bzr, the final checksum
> is 64-bit,

Actually, as best I know, it's not a checksum, just random bits (a
quick glance at the code seems to agree with me).


> Note that from a usability standpoint, the UUID's look more readable
> to a human, but are actually much worse [...]

This I agree with, at least in part.


-- 
Matthew Fuller     (MF4839)   |  fullermd@over-yonder.net
Systems/Network Administrator |  http://www.over-yonder.net/~fullermd/
           On the Internet, nobody can hear you scream.

^ permalink raw reply

* Re: VCS comparison table
From: Matthieu Moy @ 2006-10-19 16:14 UTC (permalink / raw)
  To: Tim Webster; +Cc: Christian MICHON, Andreas Ericsson, bazaar-ng, git
In-Reply-To: <72877ab10610190757u3d2b4df0o204c6ffd73af69b4@mail.gmail.com>

"Tim Webster" <tdwebste@gmail.com> writes:

> First I want to say every SCM I know of sucks when it comes to tracking
> configurations, simply because they don't record or restore file metadata,
> like perms, ownership, and acl.

That's not a simple matter.

Tracking ownership hardly makes sense as soon as you have two
developers on the same project. What does it mean to checkout a file
belonging to user foo and group bar on a system not having such user
and group?

Just restoring the complete user/group/other rwx permission is already
a mess. In my experience (GNU Arch did this):

1) It sucks ;-). Me working with umask 022 so that my collegues can
   "cp -r" from me, working on a project with people having umask 077,
   I got some files not readable, some yes, well, a mess. *I* have set
   my umask, and *I* want my tools to obey.

2) It's a security hole. If you work with people having umask=002 (not
   indecent if your default group contains just you), you end-up with
   world-writable files in your ${HOME}.

That said, it can be interesting to have it, but disabled by default.

The 'x' bit, OTOH, is definitely useful.

^ permalink raw reply

* Re: [PATCH] Don't use $author_name undefined when $from contains no /\s</.
From: Junio C Hamano @ 2006-10-19 16:19 UTC (permalink / raw)
  To: Jim Meyering; +Cc: git
In-Reply-To: <87vemgn1s2.fsf@rho.meyering.net>

Jim Meyering <jim@meyering.net> writes:

> I noticed a case not handled in a recent patch.

Thanks. Will apply.

Curiously your patch was whitespace damaged.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox