Git development
 help / color / mirror / Atom feed
* [PATCH] git-svn: avoid fetching files outside of the URL we're tracking
From: Eric Wong @ 2006-07-05 12:14 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Santi, git, Eric Wong

Thanks to Santi <sbejar@gmail.com> for the bug report and explanation:
> /path/to/repository/project/file
> /path/to/repository/project-2/file
<...>
> you end up with a project with the following files:
>
> file
> -2/file

Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
 contrib/git-svn/git-svn.perl |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl
index 08e36be..6d49109 100755
--- a/contrib/git-svn/git-svn.perl
+++ b/contrib/git-svn/git-svn.perl
@@ -2625,7 +2625,7 @@ sub libsvn_connect {
 sub libsvn_get_file {
 	my ($gui, $f, $rev) = @_;
 	my $p = $f;
-	return unless ($p =~ s#^\Q$SVN_PATH\E/?##);
+	return unless ($p =~ s#^\Q$SVN_PATH\E/##);
 
 	my ($hash, $pid, $in, $out);
 	my $pool = SVN::Pool->new;
-- 
1.4.1.ge255

^ permalink raw reply related

* Re: Can't import Xenomai svn repo
From: llandre @ 2006-07-05 10:04 UTC (permalink / raw)
  To: Dennis Stosberg; +Cc: git
In-Reply-To: <20060704101704.G3a844991@leonov.stosberg.net>

Dennis,

thanks a lot for your help.
This command starts fine but ...

git-svnimport -C xenomai2.git svn://svn.gna.org/xenomai

... after a while it fails:

Committing initial tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904
Committing initial tree 77c387d69d2880a9c3f25764b952e821af919755
Network connection closed unexpectedly: Connection closed unexpectedly 
at /usr/bin/git-svnimport line 348

-- 
llandre

DAVE Electronics System House - R&D Department
web:   http://www.dave-tech.it
email: r&d2@dave-tech.it


>> I tried to import Xenomai svn repo but the script failed:
>>
>> git-svnimport -v -C xenomai.git http://svn.gna.org/xenomai/trunk
>> RA layer request failed: PROPFIND request failed on '/xenomai/trunk': 
>> PROPFIND of '/xenomai/trunk': 405 Method Not Allowed (http://svn.gna.org) at 
>> /usr/bin/git-svnimport line 135
> 
> Looks like the repository is simply not accessible by http.
> 
>     $ svn co http://svn.gna.org/xenomai/trunk
>     svn: PROPFIND request failed on '/xenomai/trunk'
>     svn: PROPFIND of '/xenomai/trunk': 405 Method Not Allowed (http://svn.gna.org)
> 
> git-svnimport imports a complete svn repository including its
> branches and tags (as long as the svn repo follows the official
> layout).  So you would run it against the repository's root:
> 
>     git svnimport svn://svn.gna.org/xenomai/
> 
> If you want to import/track the trunk only (and maybe commit to it),
> git-svn from git's contrib is probably what you want.
> 
> Regards,
> Dennis
> 
> 

^ permalink raw reply

* Re[1]:hello from Galia S.
From: Galya S. @ 2006-07-05  9:39 UTC (permalink / raw)
  To: bk-commits-head-owner

Ave !	

I want to start my first letter from a question: "Is it possible to be happy without LOVE?"
I think that you will agree with me if the answer will be "NO WAY". Love is the most beautiful and exciting thing
that may happen between man and woman! It inspires us only for doing positive things towards each other.
One very famous writer said: "The beauty will rescue the world" i agree with his words but still i would add :
" LOVE and Beauty will rescure the world". 
I hope you agree with me that Love is a big notion.
There's love to  God, to Mother, to a child to the country where you were born, and there's love that joins a man
and woman for all their life. That is the LOVE i'm looking for! And i'm seeking for the man who is also eager to have
this life long adventure full of surprises and new experience we can share together! Will you join me for this trip?
I do realise that it should be very difficult to say "Yes" from the first letter having no idea about me.
That's why i just offer to get to know each other better though correspondence that will help us to reveal many things
about each other whether we mach perfectly or not. In addition you can look at my pictures and read some info about me here
http://foryou-mydestiny.com/
I hope you'll like what you see and read there.
Well closing my first letter to you i just want to thank you for reading it and i really hope that you'll share
my point of view on what i said above. I do really hope that you'll answer me soon.

Best regards,

Galya S.

^ permalink raw reply

* [BUG] git-svn: svn URL is a path to a directory
From: Santi @ 2006-07-05  9:26 UTC (permalink / raw)
  To: Git Mailing List

Hi *,

    currently it is used as a prefix. So, if you have a repository as:

/path/to/repository/project/file
/path/to/repository/project-2/file

and execute:
git-svn init file:///path/to/repository/project
git-svn fetch

you end up with a project with the following files:

file
-2/file

    As a real example you could try:
git-svn init svn://svn.debian.org/svn/kernel/dists/trunk/linux-2.6/
git-svn fetch -r5040:5060

   See you

   Santi
-- 
Looking for signature...
Looking for signature...done

^ permalink raw reply

* Re: Strange date format in git-send-email
From: Jakub Narebski @ 2006-07-05  9:00 UTC (permalink / raw)
  To: git
In-Reply-To: <200607050817.37366.martijn.kuipers@lx.it.pt>

Martijn Kuipers wrote:

> My email is sorted by date and a number of email-patches list the date format 
> as unknown (in kmail, that is).
> 
> When checking the headers of these mails I see the following pattern:
> 
> Date: mer, 05 jui 2006 00:36:08 +0200
> X-Mailer: git-send-email 1.4.1
> 
> Date: wto, 20 cze 2006 17:59:19 +0200
> X-Mailer: git-send-email 1.3.0
> 
> Date: Tue, Mar 14 12:12:35 2006 -0500
> User-Agent: send_patch 0.1
> 
> Date: Tue Feb 7 18:21:02 2006 +0100
[...]
> Is this my problem (or kmail), or is there something funny with 
> git-send-email? I just don't git it.

Yes, there was a problem with git-sen-email, namely it used strftime 
to print "Date:" header, but strftime is locale specific setting 
$ENV{LC_ALL} = 'C' is not enought.

There were two patches on the list: one hacky adding setlocale 
call (not applied), second implementing rfc-822 date in Perl.
Should be in current.

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* Re: [PATCH] Additional merge-base tests
From: Josef Weidendorfer @ 2006-07-05  8:39 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Johannes Schindelin, git
In-Reply-To: <7v8xn9gjh5.fsf@assigned-by-dhcp.cox.net>

On Tuesday 04 July 2006 23:15, Junio C Hamano wrote:
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > We could introduce a time.maximumSkew variable, and just walk only 
> > that much further when traversing the commits.
> 
> We could have had "commit generation number" in the commit
> object header, and use that instead of commit timestamps for
> these traversal purposes.

Isn't this "commit generation number" information that can be
regenerated on the fly, i.e. a perfect fit for data to be stored
in a persistant cache, e.g. in ".git/tmp/virtual-commit-timestamps"?

Josef

^ permalink raw reply

* Re: Experimental "git prune"
From: Johannes Schindelin @ 2006-07-05  7:57 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0607041539550.12404@g5.osdl.org>

Hi,

On Tue, 4 Jul 2006, Linus Torvalds wrote:

> static void process_tag(struct tag *tag, struct object_array *p, const char *name)
> {
> 	struct object *obj = &tag->object;
> 	struct name_path me;

AFAICS this variable is set, but not used:

> 
> 	if (obj->flags & SEEN)
> 		return;
> 	obj->flags |= SEEN;
> 
> 	me.up = NULL;
> 	me.elem = "tag:/";
> 	me.elem_len = 5;
> 
> 	if (parse_tag(tag) < 0)
> 		die("bad tag object %s", sha1_to_hex(obj->sha1));
> 	add_object(tag->tagged, p, NULL, name);
> }

As for the rest, I like it.

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH] Additional merge-base tests
From: Johannes Schindelin @ 2006-07-05  7:56 UTC (permalink / raw)
  To: A Large Angry SCM; +Cc: git, Junio C Hamano
In-Reply-To: <44AAF49F.6090008@gmail.com>

Hi,

On Tue, 4 Jul 2006, A Large Angry SCM wrote:

> Johannes Schindelin wrote:
> > Hi,
> > 
> > On Tue, 4 Jul 2006, Junio C Hamano wrote:
> > 
> > > Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> > > 
> > > > We could introduce a time.maximumSkew variable, and just walk only that
> > > > much further when traversing the commits.
> > > We could have had "commit generation number" in the commit
> > > object header, and use that instead of commit timestamps for
> > > these traversal purposes.  The generation number for a commit is
> > > defined to be max(generation number of its parents)+1 and we
> > > prime the recursive this definition by defining the generation
> > > number for the root commit to be one.
> > 
> > Are you really, really sure this is a remedy? I, for one, am quite sure of
> > the opposite. What you propose is just another time scale, only this time,
> > it is not universally true (not even minus local incompetence to keep the
> > clock accurate).
> 
> It works[*] and it does what using the timestamp was trying to do. Namely,
> work from "more recent" (or "closer") commits toward "older" (or "farther")
> commits until you've gone past the point you care about.
> 
> It's a little late to be changing the structure of a commit and you'd have to
> deal with some size/scale issues, but it's do-able. A better idea may be to
> generate and keep the generation number on a per repository basis, and you'd
> be able to work around changing grafts.

Like, inside the cache? I dunno. IMHO it is way too late to change the 
structure of a commit in that particular manner, _plus_ you would get 
overflow issues.

> [*] Grafts do _really_ nasty things to this. Just like clock skew does now.

Grafts can do much nastier things to you, for example having a circular 
history. _But_ they cannot do that nasty thing outside of your repo. Clock 
skews can.

Ciao,
Dscho

^ permalink raw reply

* Re: merge-base: update the clean-up postprocessing
From: Junio C Hamano @ 2006-07-05  7:51 UTC (permalink / raw)
  To: A Large Angry SCM; +Cc: git
In-Reply-To: <7vy7v8dctz.fsf@assigned-by-dhcp.cox.net>

A fixed up version of this patch, along with your updated test,
is at the tip of "pu".

It does affect the processing time for cases where there are
more than one merge bases negatively.  To compute all merge-base
for the 23 merges in the kernel reporitory, the old code with
the "contaminate the well a bit more" clean-up phase takes 2.5
seconds, while the new code takes 3.9 seconds.

Processing all 2215 merges in the kernel repository (the other
2192 merges have one merge-base between the parents) takes 160
seconds either way.  In other words, multi merge-base merges are
relatively rare and a bit more time spent to clean-up with the
new code is lost in the noise.

The numbers are taken from /usr/bin/time on an Athron 64X2 3800.

^ permalink raw reply

* Re: merge-base: update the clean-up postprocessing
From: Johannes Schindelin @ 2006-07-05  7:50 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: A Large Angry SCM, git
In-Reply-To: <7vy7v8dctz.fsf@assigned-by-dhcp.cox.net>

Hi,

On Tue, 4 Jul 2006, Junio C Hamano wrote:

> This is "for concepts" only -- it still seems to have bugs
> somewhere to break other tests, although it passes your new
> tests.

Doesn't this introduce a nasty O(n*m) performance (where m is the 
number of merge bases, and n the number of traversed commits)? I think 
possibly many commits are traversed multiple times.

BTW ALAS' argument about grafts not only shot down my maximumSkew, but 
AFAICT also the generation number thing. Besides, the generation number 
could be manipulated by a mean-spirited person also.

Ciao,
Dscho

^ permalink raw reply

* Strange date format in git-send-email
From: Martijn Kuipers @ 2006-07-05  7:17 UTC (permalink / raw)
  To: git

Dear list,

My email is sorted by date and a number of email-patches list the date format 
as unknown (in kmail, that is).

When checking the headers of these mails I see the following pattern:

Date: mer, 05 jui 2006 00:36:08 +0200
X-Mailer: git-send-email 1.4.1

Date: wto, 20 cze 2006 17:59:19 +0200
X-Mailer: git-send-email 1.3.0

Date: Tue, Mar 14 12:12:35 2006 -0500
User-Agent: send_patch 0.1

Date: Tue Feb 7 18:21:02 2006 +0100


Some of these are quite old, and it has been sometime since I last noticed it 
(I actually thought it was fixed). But today I received another patch-email 
from the list ([PATCH] Beautifulise git-show output), which showed the same 
problem.

Is this my problem (or kmail), or is there something funny with 
git-send-email? I just don't git it.

If you need more info, just holler.

Kind regards,
Martijn
----------------------------------------------------------------------------------------------
Actually, did actually notice actually how many times non-native English 
speaker actually use actually?

^ permalink raw reply

* Re: git-fetch per-repository speed issues
From: Jeff King @ 2006-07-05  6:47 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0607032007290.12404@g5.osdl.org>

On Mon, Jul 03, 2006 at 08:07:49PM -0700, Linus Torvalds wrote:

> > Fetching by ssh actually makes two ssh connections (the second is to
> > grab tags).
> True. Although that should happen only if there are any new tags.

Either you're wrong or there's a bug in git-fetch. 

I think you're missing the call to git-ls-remote --tags to get the list
of tags (which we will then auto-follow if necessary). So in that case,
there would actually be 3 ssh connections. If everything is up to date,
we still make 2 connections (one to check refs from remotes file, and
one to check remote tag list).

-Peff

^ permalink raw reply

* merge-base: update the clean-up postprocessing
From: Junio C Hamano @ 2006-07-05  2:07 UTC (permalink / raw)
  To: A Large Angry SCM; +Cc: git
In-Reply-To: <44AB0948.9070606@gmail.com>

This is "for concepts" only -- it still seems to have bugs
somewhere to break other tests, although it passes your new
tests.
-- >8 --
This removes the "contaminate the well even more" approach
taken in the current merge-base postprosessing code.  Instead,
when there are more than one merge-base results, we compute the
merge-base between them and see if one is a fast-forward of the
other, in which case the ancestor is removed from the result.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---

 * This is on top of Johannes/Rene's merge-base work (in "next").

 commit.c |  279 ++++++++++++++++++++------------------------------------------
 1 files changed, 89 insertions(+), 190 deletions(-)

diff --git a/commit.c b/commit.c
index c6bf10d..1bd6dca 100644
--- a/commit.c
+++ b/commit.c
@@ -854,6 +854,7 @@ void sort_in_topological_order_fn(struct
 #define PARENT1		(1u<< 8)
 #define PARENT2		(1u<< 9)
 #define STALE		(1u<<10)
+#define RESULT		(1u<<11)
 
 static struct commit *interesting(struct commit_list *list)
 {
@@ -867,183 +868,42 @@ static struct commit *interesting(struct
 	return NULL;
 }
 
-/*
- * A pathological example of how this thing works.
- *
- * Suppose we had this commit graph, where chronologically
- * the timestamp on the commit are A <= B <= C <= D <= E <= F
- * and we are trying to figure out the merge base for E and F
- * commits.
- *
- *                  F
- *                 / \
- *            E   A   D
- *             \ /   /
- *              B   /
- *               \ /
- *                C
- *
- * First we push E and F to list to be processed.  E gets bit 1
- * and F gets bit 2.  The list becomes:
- *
- *     list=F(2) E(1), result=empty
- *
- * Then we pop F, the newest commit, from the list.  Its flag is 2.
- * We scan its parents, mark them reachable from the side that F is
- * reachable from, and push them to the list:
- *
- *     list=E(1) D(2) A(2), result=empty
- *
- * Next pop E and do the same.
- *
- *     list=D(2) B(1) A(2), result=empty
- *
- * Next pop D and do the same.
- *
- *     list=C(2) B(1) A(2), result=empty
- *
- * Next pop C and do the same.
- *
- *     list=B(1) A(2), result=empty
- *
- * Now it is B's turn.  We mark its parent, C, reachable from B's side,
- * and push it to the list:
- *
- *     list=C(3) A(2), result=empty
- *
- * Now pop C and notice it has flags==3.  It is placed on the result list,
- * and the list now contains:
- *
- *     list=A(2), result=C(3)
- *
- * We pop A and do the same.
- *
- *     list=B(3), result=C(3)
- *
- * Next, we pop B and something very interesting happens.  It has flags==3
- * so it is also placed on the result list, and its parents are marked
- * stale, retroactively, and placed back on the list:
- *
- *    list=C(7), result=C(7) B(3)
- *
- * Now, list does not have any interesting commit.  So we find the newest
- * commit from the result list that is not marked stale.  Which is
- * commit B.
- *
- *
- * Another pathological example how this thing used to fail to mark an
- * ancestor of a merge base as STALE before we introduced the
- * postprocessing phase (mark_reachable_commits).
- *
- *		  2
- *		  H
- *	    1    / \
- *	    G   A   \
- *	    |\ /     \
- *	    | B       \
- *	    |  \       \
- *	     \  C       F
- *	      \  \     /
- *	       \  D   /
- *		\ |  /
- *		 \| /
- *		  E
- *
- *	 list			A B C D E F G H
- *	 G1 H2			- - - - - - 1 2
- *	 H2 E1 B1		- 1 - - 1 - 1 2
- *	 F2 E1 B1 A2		2 1 - - 1 2 1 2
- *	 E3 B1 A2		2 1 - - 3 2 1 2
- *	 B1 A2			2 1 - - 3 2 1 2
- *	 C1 A2			2 1 1 - 3 2 1 2
- *	 D1 A2			2 1 1 1 3 2 1 2
- *	 A2			2 1 1 1 3 2 1 2
- *	 B3			2 3 1 1 3 2 1 2
- *	 C7			2 3 7 1 3 2 1 2
- *
- * At this point, unfortunately, everybody in the list is
- * stale, so we fail to complete the following two
- * steps to fully marking stale commits.
- *
- *	 D7			2 3 7 7 3 2 1 2
- *	 E7			2 3 7 7 7 2 1 2
- *
- * and we ended up showing E as an interesting merge base.
- * The postprocessing phase re-injects C and continues traversal
- * to contaminate D and E.
- */
-
-static void mark_reachable_commits(struct commit_list *result,
-				   struct commit_list *list)
-{
-	struct commit_list *tmp;
-
-	/*
-	 * Postprocess to fully contaminate the well.
-	 */
-	for (tmp = result; tmp; tmp = tmp->next) {
-		struct commit *c = tmp->item;
-		/* Reinject stale ones to list,
-		 * so we can scan their parents.
-		 */
-		if (c->object.flags & STALE)
-			commit_list_insert(c, &list);
-	}
-	while (list) {
-		struct commit *c = list->item;
-		struct commit_list *parents;
-
-		tmp = list;
-		list = list->next;
-		free(tmp);
-
-		/* Anything taken out of the list is stale, so
-		 * mark all its parents stale.  We do not
-		 * parse new ones (we already parsed all the relevant
-		 * ones).
-		 */
-		parents = c->parents;
-		while (parents) {
-			struct commit *p = parents->item;
-			parents = parents->next;
-			if (!(p->object.flags & STALE)) {
-				p->object.flags |= STALE;
-				commit_list_insert(p, &list);
-			}
-		}
-	}
-}
-
-struct commit_list *get_merge_bases(struct commit *rev1, struct commit *rev2,
-                                    int cleanup)
+static struct commit_list *merge_bases(struct commit *one, struct commit *two)
 {
 	struct commit_list *list = NULL;
 	struct commit_list *result = NULL;
-	struct commit_list *tmp = NULL;
 
-	if (rev1 == rev2)
-		return commit_list_insert(rev1, &result);
+	if (one == two)
+		/* We do not mark this even with RESULT so we do not
+		 * have to clean it up.
+		 */
+		return commit_list_insert(one, &result);
 
-	parse_commit(rev1);
-	parse_commit(rev2);
+	parse_commit(one);
+	parse_commit(two);
 
-	rev1->object.flags |= PARENT1;
-	rev2->object.flags |= PARENT2;
-	insert_by_date(rev1, &list);
-	insert_by_date(rev2, &list);
+	one->object.flags |= PARENT1;
+	two->object.flags |= PARENT2;
+	insert_by_date(one, &list);
+	insert_by_date(two, &list);
 
 	while (interesting(list)) {
-		struct commit *commit = list->item;
+		struct commit *commit;
 		struct commit_list *parents;
-		int flags = commit->object.flags
-			& (PARENT1 | PARENT2 | STALE);
+		struct commit_list *n;
+		int flags;
 
-		tmp = list;
-		list = list->next;
-		free(tmp);
-		if (flags == (PARENT1 | PARENT2)) {
-			insert_by_date(commit, &result);
+		commit = list->item;
+		n = list->next;
+		free(list);
+		list = n;
 
+		flags = commit->object.flags & (PARENT1 | PARENT2 | STALE);
+		if (flags == (PARENT1 | PARENT2)) {
+			if (!(commit->object.flags & RESULT)) {
+				commit->object.flags |= RESULT;
+				insert_by_date(commit, &result);
+			}
 			/* Mark parents of a found merge stale */
 			flags |= STALE;
 		}
@@ -1059,35 +919,74 @@ struct commit_list *get_merge_bases(stru
 		}
 	}
 
-	if (!result)
-		goto finish;
-
-	if (result->next && list)
-		mark_reachable_commits(result, list);
+	/* Clean up the result to remove stale ones */
+	list = result; result = NULL;
+	while (list) {
+		struct commit_list *n = list->next;
+		if (!(list->item->object.flags & STALE))
+			insert_by_date(list->item, &result);
+		free(list);
+		list = n;
+	}
+	return result;
+}
 
-	/* cull duplicates */
-	for (tmp = result, list = NULL; tmp; ) {
-		struct commit *commit = tmp->item;
-		struct commit_list *next = tmp->next;
-		if (commit->object.flags & STALE) {
-			if (list != NULL)
-				list->next = next;
-			free(tmp);
-		} else {
-			if (list == NULL)
-				result = tmp;
-			list = tmp;
-			commit->object.flags |= STALE;
+struct commit_list *get_merge_bases(struct commit *one,
+				    struct commit *two,
+                                    int cleanup)
+{
+	struct commit_list *result = merge_bases(one, two);
+	struct commit_list *list;
+	struct commit **rslt;
+	unsigned all_flags = (PARENT1 | PARENT2 | STALE | RESULT);
+	int cnt, i, j;
+
+	if (one == two)
+		return result;
+	if (!result || !result->next) {
+		if (cleanup) {
+			clear_commit_marks(one, all_flags);
+			clear_commit_marks(two, all_flags);
 		}
-
-		tmp = next;
+		return result;
 	}
 
- finish:
-	if (cleanup) {
-		clear_commit_marks(rev1, PARENT1 | PARENT2 | STALE);
-		clear_commit_marks(rev2, PARENT1 | PARENT2 | STALE);
+	/* There are more than one */
+	cnt = 0;
+	list = result;
+	while (list) {
+		list = list->next;
+		cnt++;
+	}
+	rslt = xcalloc(cnt, sizeof(*rslt));
+	for (list = result, i = 0; list; list = list->next)
+		rslt[i] = list->item;
+	free_commit_list(result);
+
+	clear_commit_marks(one, all_flags);
+	clear_commit_marks(two, all_flags);
+	for (i = 0; i < cnt - 1; i++) {
+		for (j = i+1; j < cnt; j++) {
+			if (!rslt[i] || !rslt[j])
+				continue;
+			result = merge_bases(rslt[i], rslt[j]);
+			clear_commit_marks(rslt[i], all_flags);
+			clear_commit_marks(rslt[j], all_flags);
+			for (list = result; list; list = list->next) {
+				if (rslt[i] == list->item)
+					rslt[i] = NULL;
+				if (rslt[j] == list->item)
+					rslt[j] = NULL;
+			}
+		}
 	}
 
+	/* Surviving ones in rslt[] are the independent results */
+	result = NULL;
+	for (i = 0; i < cnt; i++) {
+		if (rslt[i])
+			insert_by_date(rslt[i], &result);
+	}
+	free(rslt);
 	return result;
 }
-- 
1.4.1.g7993

^ permalink raw reply related

* Re: [PATCH] Additional merge-base tests
From: Junio C Hamano @ 2006-07-05  0:59 UTC (permalink / raw)
  To: git
In-Reply-To: <7vpsgllsnp.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano <junkio@cox.net> writes:

> It may be interesting to run tests on real merges (I believe the
> kernel repository has a handful merges that have more than one
> merge bases) to see how effective the current clean-up pass is.
> It may turn out to be ineffective in practice, in which case we
> could kill it off.

So I counted.

There are 23 commits in the kernel history that have more than
one merge-bases.  The current merge-base code tells us that all
of them have two merge-bases.

None of them suffers from the horizon effect; the two bases
are not ancestor/descendant of each other.

A good news is that get_merge_bases() gives the same answer
without the clean-up pass mark_reachable_commits().

d0e5f39f1ee2e55d140064bb6d74c8bad25d71d0
361ea93cbff0e42cbc6a0f3c7a8238db9ed15648
4b2d9cf00962d0a0e697f887f3ecaa155cbde555
ba9b28d19a3251bb1dfe6a6f8cc89b96fb85f683
db21e578e551421d76641d72cb3f8296ed3f9e61
b425c8c5922562c562dc55a636c3c8d758ed6d17
2e9ff56efbc005ab2b92b68df65940c7459446c6
75e47b36004d136edff68295420424cba3a5ccd0
c45ae87ec9d03c9adfc466a6b560cb38b154813a
09e4f9029da1b53e835555c353a89c36b71233b0
0b310f36d7d96e27f6941ec0f9b95e15142f1e78
db9ace7083dbdcc3d02bdd6a1d26132c80b5b726
80c7af4074cbb4cb6be5d35c443ea6d5e8838a84
701db69d6647f61e4660c9102d7f2fd5dffc203d
5e3c2b95dd560baa41b08c8f5f00bbd6fbeebdcb
c7fb577e2a6cb04732541f2dc402bd46747f7558
ba9b543d5bec0a7605952e2ba501fb8b0f3b6407
84ffa747520edd4556b136bdfc9df9eb1673ce12
da28c12089dfcfb8695b6b555cdb8e03dda2b690
3190186362466658f01b2e354e639378ce07e1a9
0c168775709faa74c1b87f1e61046e0c51ade7f3
0e396ee43e445cb7c215a98da4e76d0ce354d9d7
467ca22d3371f132ee225a5591a1ed0cd518cb3d

^ permalink raw reply

* [PATCH] Additional merge-base tests (revised)
From: A Large Angry SCM @ 2006-07-05  0:35 UTC (permalink / raw)
  To: Junio C Hamano, git

Signed-off-by: A Large Angry SCM <gitzilla@gmail.com>
---
This demonstrates a problem with git-merge-base.

This is a slightly revised version of the same patch as before.

 t/t6010-merge-base.sh |   45 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 45 insertions(+)

diff --git a/t/t6010-merge-base.sh b/t/t6010-merge-base.sh
index 1dce123..2b7b51c 100755
--- a/t/t6010-merge-base.sh
+++ b/t/t6010-merge-base.sh
@@ -44,6 +44,43 @@ A=$(doit 1 A $B)
 G=$(doit 7 G $B $E)
 H=$(doit 8 H $A $F)
 
+# Setup for second test to demonstrate that relying on timestamps in a
+# distributed SCM to provide a _consistent_ partial ordering of commits
+# leads to insanity.
+#
+#               Relative
+# Structure     timestamps
+#
+#   PL  PR        +4  +4
+#  /  \/  \      /  \/  \
+# L2  C2  R2    +3  -1  +3
+# |   |   |     |   |   |
+# L1  C1  R1    +2  -2  +2
+# |   |   |     |   |   |
+# L0  C0  R0    +1  -3  +1
+#   \ |  /        \ |  /
+#     S             0
+#
+# The left and right chains of commits can be of any length and complexity as
+# long as all of the timestamps are greater than that of S.
+
+S=$(doit  0 S)
+
+C0=$(doit -3 C0 $S)
+C1=$(doit -2 C1 $C0)
+C2=$(doit -1 C2 $C1)
+
+L0=$(doit  1 L0 $S)
+L1=$(doit  2 L1 $L0)
+L2=$(doit  3 L2 $L1)
+
+R0=$(doit  1 R0 $S)
+R1=$(doit  2 R1 $R0)
+R2=$(doit  3 R2 $R1)
+
+PL=$(doit  4 PL $L2 $C2)
+PR=$(doit  4 PR $C2 $R2)
+
 test_expect_success 'compute merge-base (single)' \
     'MB=$(git-merge-base G H) &&
      expr "$(git-name-rev "$MB")" : "[0-9a-f]* tags/B"'
@@ -56,4 +93,12 @@ test_expect_success 'compute merge-base 
     'MB=$(git-show-branch --merge-base G H) &&
      expr "$(git-name-rev "$MB")" : "[0-9a-f]* tags/B"'
 
+test_expect_success 'compute merge-base (single)' \
+    'MB=$(git-merge-base PL PR) &&
+     expr "$(git-name-rev "$MB")" : "[0-9a-f]* tags/C2"'
+
+test_expect_success 'compute merge-base (all)' \
+    'MB=$(git-merge-base --all PL PR) &&
+     expr "$(git-name-rev "$MB")" : "[0-9a-f]* tags/C2"'
+
 test_done

^ permalink raw reply related

* Re: [PATCH] Additional merge-base tests
From: A Large Angry SCM @ 2006-07-05  0:26 UTC (permalink / raw)
  To: Jakub Narebski, git
In-Reply-To: <e8esnn$mb5$1@sea.gmane.org>

Jakub Narebski wrote:
> A Large Angry SCM wrote:
> 
>> It works[*] and it does what using the timestamp was trying to do. 
>> Namely, work from "more recent" (or "closer") commits toward "older" (or 
>> "farther") commits until you've gone past the point you care about.
>>
>> It's a little late to be changing the structure of a commit and you'd 
>> have to deal with some size/scale issues, but it's do-able. A better 
>> idea may be to generate and keep the generation number on a per 
>> repository basis, and you'd be able to work around changing grafts.
> 
> What about timestamp = MAX(now(), timestamps of parents) idea, which
> doesn't need changing the structure of a commit?
> 

So, do you really want your name as committer on a commit with a date 
300 years in the future because one of the parents had a bad date?

^ permalink raw reply

* Re: [PATCH] Additional merge-base tests
From: Junio C Hamano @ 2006-07-05  0:24 UTC (permalink / raw)
  To: gitzilla, Johannes Schindelin; +Cc: git
In-Reply-To: <44AAF49F.6090008@gmail.com>

A Large Angry SCM <gitzilla@gmail.com> writes:

>
> It works[*] and it does what using the timestamp was trying to
> do. Namely, work from "more recent" (or "closer") commits toward
> "older" (or "farther") commits until you've gone past the point you
> care about.

If you really really care, now we have clear_commit_marks() with
get_merge_bases() infrastructure in, you _could_ run another
round of get_merge_bases() on the commit on the result list to
see which ones are reachable from others by performing an
equivalent of fast-forward/already-up-to-date check.

^ permalink raw reply

* Re: [PATCH] Additional merge-base tests
From: Junio C Hamano @ 2006-07-04 23:39 UTC (permalink / raw)
  To: jnareb; +Cc: git
In-Reply-To: <e8esnn$mb5$1@sea.gmane.org>

Jakub Narebski <jnareb@gmail.com> writes:

> What about timestamp = MAX(now(), timestamps of parents) idea, which
> doesn't need changing the structure of a commit?

It changes the semantics without change syntax, which is not any
better (and in fact I think it is worse).

^ permalink raw reply

* Re: [PATCH] Additional merge-base tests
From: Jakub Narebski @ 2006-07-04 23:14 UTC (permalink / raw)
  To: git
In-Reply-To: <44AAF49F.6090008@gmail.com>

A Large Angry SCM wrote:

> It works[*] and it does what using the timestamp was trying to do. 
> Namely, work from "more recent" (or "closer") commits toward "older" (or 
> "farther") commits until you've gone past the point you care about.
> 
> It's a little late to be changing the structure of a commit and you'd 
> have to deal with some size/scale issues, but it's do-able. A better 
> idea may be to generate and keep the generation number on a per 
> repository basis, and you'd be able to work around changing grafts.

What about timestamp = MAX(now(), timestamps of parents) idea, which
doesn't need changing the structure of a commit?

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* Re: [PATCH] Additional merge-base tests
From: A Large Angry SCM @ 2006-07-04 23:07 UTC (permalink / raw)
  To: Johannes Schindelin, git; +Cc: Junio C Hamano
In-Reply-To: <Pine.LNX.4.63.0607050021330.29667@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin wrote:
> Hi,
> 
> On Tue, 4 Jul 2006, Junio C Hamano wrote:
> 
>> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>>
>>> We could introduce a time.maximumSkew variable, and just walk only 
>>> that much further when traversing the commits.
>> We could have had "commit generation number" in the commit
>> object header, and use that instead of commit timestamps for
>> these traversal purposes.  The generation number for a commit is
>> defined to be max(generation number of its parents)+1 and we
>> prime the recursive this definition by defining the generation
>> number for the root commit to be one.
> 
> Are you really, really sure this is a remedy? I, for one, am quite sure of 
> the opposite. What you propose is just another time scale, only this time, 
> it is not universally true (not even minus local incompetence to keep the 
> clock accurate).

It works[*] and it does what using the timestamp was trying to do. 
Namely, work from "more recent" (or "closer") commits toward "older" (or 
"farther") commits until you've gone past the point you care about.

It's a little late to be changing the structure of a commit and you'd 
have to deal with some size/scale issues, but it's do-able. A better 
idea may be to generate and keep the generation number on a per 
repository basis, and you'd be able to work around changing grafts.

[*] Grafts do _really_ nasty things to this. Just like clock skew does now.

^ permalink raw reply

* Re: [PATCH] Beautifulise git-show output
From: Bertrand Jacquin @ 2006-07-04 22:59 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vejx1f0fz.fsf@assigned-by-dhcp.cox.net>

On 7/5/06, Junio C Hamano <junkio@cox.net> wrote:
> Why?
>
> A patch like this needs to be justified with a bit more
> explanation; the word "beautiful" is subjective.

Arg, git-send-email seems to made a bad job after git-format-patch, sorry.

So explanation don't go here. So here it is :
Git-show actually show (for example) :

    Makefile: Create Makefile for Beamer theme
    rules are : install & uninstall (be careful on this one)

    Also, I hacked presentation oral's Makefile to check them presence or not
---

 docs/presentation_oral/Makefile        |    5 +-
 docs/presentation_oral/themes/Makefile |   91 ++++++++++++++++++++++++++++++++
 2 files changed, 95 insertions(+), 1 deletions(-)
 create mode 100644 docs/presentation_oral/themes/Makefile

I would like to have a newline after commit mesage too as there is one
before diff-stat.

-- 
# Beber : beber@gna.org
# IM : beber@jabber.fr
# http://guybrush.ath.cx, irc://irc.freenode.net/#{e.fr,gentoofr}

^ permalink raw reply

* Re: Experimental "git prune"
From: Junio C Hamano @ 2006-07-04 22:55 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0607041539550.12404@g5.osdl.org>

Linus Torvalds <torvalds@osdl.org> writes:

> This is an example of how "git prune" could be speeded up a lot.

Ah, you are avoiding the verification cost of fsck-objects.  Neat.

^ permalink raw reply

* Re: [PATCH] Beautifulise git-show output
From: Junio C Hamano @ 2006-07-04 22:51 UTC (permalink / raw)
  To: beber.mailing; +Cc: git
In-Reply-To: <11520525682686-git-send-email-beber.mailing@gmail.com>

Why?

A patch like this needs to be justified with a bit more
explanation; the word "beautiful" is subjective.

(current)
	Change this and that file

        Signed-off-by: A U Thor <a.u.thor@example.com>
	---
         this-file |   20 +++++++----
	 that-file |    4 ++++
	 2 files changed, 20 insertions(+), 4 deletions(-)

        diff --git a/this-file b/this-file
	...
 
(yours -- and I think 1.3.0 did it like this)
	Change this and that file

        Signed-off-by: A U Thor <a.u.thor@example.com>

	---
         this-file |   20 +++++++----
	 that-file |    4 ++++
	 2 files changed, 20 insertions(+), 4 deletions(-)

        diff --git a/this-file b/this-file
	...
 
It _might_ be easier to read if it were like this, though:
 
	Change this and that file

        Signed-off-by: A U Thor <a.u.thor@example.com>
	---

         this-file |   20 +++++++----
	 that-file |    4 ++++
	 2 files changed, 20 insertions(+), 4 deletions(-)

        diff --git a/this-file b/this-file
	...

However, the screen real estate, especially in the vertical
direction, is a scarce resource; I do not think the three-dash
is a too weak visual separator that needs to be helped by an
extra newline.

^ permalink raw reply

* Re: [PATCH] Additional merge-base tests
From: Junio C Hamano @ 2006-07-04 22:42 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.63.0607050021330.29667@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> If that should be not true, you always could rely on topo order. Which 
> does not seem to solve the problem for you.

The computation of merge-base is about computing topo order
cheaply, so that is a recursive definition of the problem, not a
solution, I am afraid.  

With the generation counter, we know the clean-up phase needs to
parse and traverse unparsed parents with the same or higher
generation counter than the lowest we have in the result list,
which would limit our clean-up traversal.  In order to look at
the generation number of parent, we would need to parse it, so
we would end up parsing one level more than needed at the edge,
though.

^ permalink raw reply

* Experimental "git prune"
From: Linus Torvalds @ 2006-07-04 22:41 UTC (permalink / raw)
  To: Junio C Hamano, Git Mailing List


This is an example of how "git prune" could be speeded up a lot.

This needs the builtin magic to actually enable it, and the "printf" needs 
to be made a real unlink, but as far as I can tell it actually works.

Comments?

		Linus

----
/*
 * builtin-prune.c
 */
#include "cache.h"
#include "refs.h"
#include "tag.h"
#include "commit.h"
#include "tree.h"
#include "blob.h"
#include "tree-walk.h"
#include "diff.h"
#include "revision.h"
#include "builtin.h"
#include "cache-tree.h"

static struct rev_info revs;

static int prune_object(char *path, const char *filename, const unsigned char *sha1)
{
	printf("%s/%s should be pruned\n", path, filename);
	return 0;
}

static int prune_dir(int i, char *path)
{
	DIR *dir = opendir(path);
	struct dirent *de;

	if (!dir)
		return 0;

	while ((de = readdir(dir)) != NULL) {
		char name[100];
		unsigned char sha1[20];
		int len = strlen(de->d_name);

		switch (len) {
		case 2:
			if (de->d_name[1] != '.')
				break;
		case 1:
			if (de->d_name[0] != '.')
				break;
			continue;
		case 38:
			sprintf(name, "%02x", i);
			memcpy(name+2, de->d_name, len+1);
			if (get_sha1_hex(name, sha1) < 0)
				break;

			/*
			 * Do we know about this object?
			 * It must have been reachable
			 */
			if (lookup_object(sha1))
				continue;

			prune_object(path, de->d_name, sha1);
			continue;
		}
		fprintf(stderr, "bad sha1 file: %s/%s\n", path, de->d_name);
	}
	closedir(dir);
	return 0;
}

static void prune_object_dir(const char *path)
{
	int i;
	for (i = 0; i < 256; i++) {
		static char dir[4096];
		sprintf(dir, "%s/%02x", path, i);
		prune_dir(i, dir);
	}
}

static void process_blob(struct blob *blob,
			 struct object_array *p,
			 struct name_path *path,
			 const char *name)
{
	struct object *obj = &blob->object;

	if (obj->flags & SEEN)
		return;
	obj->flags |= SEEN;
	/* Nothing to do, really .. The blob lookup was the important part */
}

static void process_tree(struct tree *tree,
			 struct object_array *p,
			 struct name_path *path,
			 const char *name)
{
	struct object *obj = &tree->object;
	struct tree_desc desc;
	struct name_entry entry;
	struct name_path me;

	if (obj->flags & SEEN)
		return;
	obj->flags |= SEEN;
	if (parse_tree(tree) < 0)
		die("bad tree object %s", sha1_to_hex(obj->sha1));
	name = strdup(name);
	add_object(obj, p, path, name);
	me.up = path;
	me.elem = name;
	me.elem_len = strlen(name);

	desc.buf = tree->buffer;
	desc.size = tree->size;

	while (tree_entry(&desc, &entry)) {
		if (S_ISDIR(entry.mode))
			process_tree(lookup_tree(entry.sha1), p, &me, entry.path);
		else
			process_blob(lookup_blob(entry.sha1), p, &me, entry.path);
	}
	free(tree->buffer);
	tree->buffer = NULL;
}

static void process_tag(struct tag *tag, struct object_array *p, const char *name)
{
	struct object *obj = &tag->object;
	struct name_path me;

	if (obj->flags & SEEN)
		return;
	obj->flags |= SEEN;

	me.up = NULL;
	me.elem = "tag:/";
	me.elem_len = 5;

	if (parse_tag(tag) < 0)
		die("bad tag object %s", sha1_to_hex(obj->sha1));
	add_object(tag->tagged, p, NULL, name);
}

static void walk_commit_list(struct rev_info *revs)
{
	int i;
	struct commit *commit;
	struct object_array objects = { 0, 0, NULL };

	/* Walk all commits, process their trees */
	while ((commit = get_revision(revs)) != NULL)
		process_tree(commit->tree, &objects, NULL, "");

	/* Then walk all the pending objects, recursively processing them too */
	for (i = 0; i < revs->pending.nr; i++) {
		struct object_array_entry *pending = revs->pending.objects + i;
		struct object *obj = pending->item;
		const char *name = pending->name;
		if (obj->type == TYPE_TAG) {
			process_tag((struct tag *) obj, &objects, name);
			continue;
		}
		if (obj->type == TYPE_TREE) {
			process_tree((struct tree *)obj, &objects, NULL, name);
			continue;
		}
		if (obj->type == TYPE_BLOB) {
			process_blob((struct blob *)obj, &objects, NULL, name);
			continue;
		}
		die("unknown pending object %s (%s)", sha1_to_hex(obj->sha1), name);
	}
}

static int add_one_ref(const char *path, const unsigned char *sha1)
{
	struct object *object = parse_object(sha1);
	if (!object)
		die("bad object ref: %s:%s", path, sha1_to_hex(sha1));
	add_pending_object(&revs, object, "");
	return 0;        
}

static void add_one_tree(const unsigned char *sha1)
{
	struct tree *tree = lookup_tree(sha1);
	add_pending_object(&revs, &tree->object, "");
}

static void add_cache_tree(struct cache_tree *it)
{
	int i;

	if (it->entry_count >= 0)
		add_one_tree(it->sha1);
	for (i = 0; i < it->subtree_nr; i++)
		add_cache_tree(it->down[i]->cache_tree);
}

static void add_cache_refs(void)
{
	int i;

 	read_cache();
	for (i = 0; i < active_nr; i++) {
		lookup_blob(active_cache[i]->sha1);
		/*
		 * We could add the blobs to the pending list, but quite
		 * frankly, we don't care. Once we've looked them up, and
		 * added them as objects, we've really done everything 
		 * there is to do for a blob
		 */
	}
	if (active_cache_tree)
		add_cache_tree(active_cache_tree);
}

int cmd_prune(int argc, const char **argv, char **envp)
{
	/*
	 * Set up revision parsing, and mark us as being interested
	 * in all object types, not just commits.
	 */
	init_revisions(&revs);
	revs.tag_objects = 1;
	revs.blob_objects = 1;
	revs.tree_objects = 1;

	/* Add all external refs */
	for_each_ref(add_one_ref);

	/* Add all refs from the index file */
	add_cache_refs();

	/*
	 * Set up the revision walk - this will move all commits
	 * from the pending list to the commit walking list.
	 */
	prepare_revision_walk(&revs);

	walk_commit_list(&revs);

	prune_object_dir(get_object_directory());

	return 0;
}

^ 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