* Re: [PATCH v3] Add script for importing bits-and-pieces to Git.
From: Peter Krefting @ 2009-08-26 9:08 UTC (permalink / raw)
To: git
In-Reply-To: <20090826090426.D6C73189B12@perkele>
Peter Krefting:
> This version contains updated documentation, trying to address the
> points raised by Junio. It also fixes a compile error that snuck in
> the v2 patch.
No it doesn't. I seem to have sent out v2 again under a new name. Sorry for
the noise :-)
--
\\// Peter - http://www.softwolves.pp.se/
^ permalink raw reply
* [PATCH v3.1] Add script for importing bits-and-pieces to Git.
From: Peter Krefting @ 2009-08-24 17:09 UTC (permalink / raw)
To: git
Allows the user to import version history that is stored in bits and
pieces in the file system, for instance snapshots of old development
trees, or day-by-day backups. A configuration file is used to
describe the relationship between the different files and allow
describing branches and merges, as well as authorship and commit
messages.
Output is created in a format compatible with git-fast-import.
Full documentation is provided inline in perldoc format.
Signed-off-by: Peter Krefting <peter@softwolves.pp.se>
---
This version contains updated documentation, trying to address the
points raised by Junio. It also fixes a compile error that snuck in
the v2 patch.
contrib/fast-import/import-directories.perl | 359 +++++++++++++++++++++++++++
1 files changed, 359 insertions(+), 0 deletions(-)
create mode 100755 contrib/fast-import/import-directories.perl
diff --git a/contrib/fast-import/import-directories.perl b/contrib/fast-import/import-directories.perl
new file mode 100755
index 0000000..a5429d3
--- /dev/null
+++ b/contrib/fast-import/import-directories.perl
@@ -0,0 +1,359 @@
+#!/usr/bin/perl -w
+#
+# Copyright 2008-2009 Peter Krefting <peter@softwolves.pp.se>
+#
+# ------------------------------------------------------------------------
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+# ------------------------------------------------------------------------
+
+=pod
+
+=head1 NAME
+
+import-directories - Import bits and pieces to Git.
+
+=head1 SYNOPSIS
+
+B<import-directories.perl> F<configfile>
+
+=head1 DESCRIPTION
+
+Script to import arbitrary projects version controlled by the "copy the
+source directory to a new location and edit it there"-version controlled
+projects into version control. Handles projects with arbitrary branching
+and version trees, taking a file describing the inputs and generating a
+file compatible with the L<git-fast-import(1)> format.
+
+=head1 CONFIGURATION FILE
+
+=head2 Format
+
+The configuration file is based on the standard I<.ini> format.
+
+ ; Comments start with semi-colons
+ [section]
+ key=value
+
+Unlike the git-config format, no quoting characters are allowed, all
+section and key names are case-sensitive and whitespace is preserved
+as-is. For example:
+
+ key1 =value1
+ key2= value2
+
+Here the first key is "key1 " (note the trailing white-space) and the
+second value is " value2" (note the leading white-space). Keys cannot
+contain equal signs ("=").
+
+=head2 Global configuration
+
+Global configuration is done in the B<[config]> section, which should be
+the first section in the file. Configuration can be changed by
+repeating configuration sections later on.
+
+ [config]
+ ; configure conversion of CRLFs. "convert" means that all CRLFs
+ ; should be converted into LFs (suitable for the core.autocrlf
+ ; setting set to true in Git). "none" means that all data is
+ ; treated as binary.
+ crlf=convert
+
+=head2 Revision configuration
+
+Each revision that is to be imported is described in three
+sections. Revisions should be defined in topological order, so
+that a revision's parent has always been defined when a new revision
+is introduced. All the sections for one revision must be defined
+before defining the next revision.
+
+Each revision is assigned a unique numerical identifier. The
+numbers do not need to be consecutive, nor monotonically
+increasing.
+
+For instance, if your configuration file contains only the two
+revisions 4711 and 42, where 4711 is the initial commit, the
+only requirement is that 4711 is completely defined before 42.
+
+=pod
+
+=head3 Revision description section
+
+A section whose section name is just an integer gives meta-data
+about the revision.
+
+ [3]
+ ; author sets the author of the revisions
+ author=Peter Krefting <peter@softwolves.pp.se>
+ ; branch sets the branch that the revision should be committed to
+ branch=master
+ ; parent describes the revision that is the parent of this commit
+ ; (optional)
+ parent=1
+ ; merges describes a revision that is merged into this commit
+ ; (optional; can be repeated)
+ merges=2
+ ; selects one file to take the timestamp from
+ ; (optional; if unspecified, the most recent file from the .files
+ ; section is used)
+ timestamp=3/source.c
+
+=head3 Revision contents section
+
+A section whose section name is an integer followed by B<.files>
+describe all the files included in this revision. If a file that
+was available previously is not included in this revision, it will
+be removed.
+
+If an on-disk revision is incomplete, you can point to files from
+a previous revision. There are no restriction as to where the source
+files are located, nor to the names of them.
+
+ [3.files]
+ ; the key is the path inside the repository, the value is the path
+ ; as seen from the importer script.
+ source.c=ver-3.00/source.c
+ source.h=ver-2.99/source.h
+ readme.txt=ver-3.00/introduction to the project.txt
+
+=head3 Revision commit message section
+
+A section whose section name is an integer followed by B<.message>
+gives the commit message. This section is read verbatim, up until
+the beginning of the next section. As such, a commit message may not
+contain a line that begins with an opening square bracket ("[") and
+ends with a closing square bracket ("]"), unless they are surrounded
+by whitespace or other characters.
+
+ [3.message]
+ Implement foobar.
+ ; trailing blank lines are ignored.
+
+=cut
+
+# Globals
+use strict;
+use integer;
+my $crlfmode = 0;
+my @revs;
+my (%revmap, %message, %files, %author, %branch, %parent, %merges, %time, %timesource);
+my $sectiontype = 0;
+my $rev = 0;
+my $mark = 1;
+
+# Check command line
+if ($#ARGV == -1 || $ARGV[0] =~ /^--?h/)
+{
+ exec('perldoc', $0);
+ exit 1;
+}
+
+# Open configuration
+my $config = $ARGV[0];
+open CFG, '<', $config or die "Cannot open configuration file \"$config\": ";
+
+# Open output
+my $output = $ARGV[1];
+open OUT, '>', $output or die "Cannot create output file \"$output\": ";
+binmode OUT;
+
+LINE: while (my $line = <CFG>)
+{
+ $line =~ s/\r?\n$//;
+ next LINE if $sectiontype != 4 && $line eq '';
+ next LINE if $line =~ /^;/;
+ my $oldsectiontype = $sectiontype;
+ my $oldrev = $rev;
+
+ # Sections
+ if ($line =~ m"^\[(config|(\d+)(|\.files|\.message))\]$")
+ {
+ if ($1 eq 'config')
+ {
+ $sectiontype = 1;
+ }
+ elsif ($3 eq '')
+ {
+ $sectiontype = 2;
+ $rev = $2;
+ # Create a new revision
+ die "Duplicate rev: $line\n " if defined $revmap{$rev};
+ print "Reading revision $rev\n";
+ push @revs, $rev;
+ $revmap{$rev} = $mark ++;
+ $time{$revmap{$rev}} = 0;
+ }
+ elsif ($3 eq '.files')
+ {
+ $sectiontype = 3;
+ $rev = $2;
+ die "Revision mismatch: $line\n " unless $rev == $oldrev;
+ }
+ elsif ($3 eq '.message')
+ {
+ $sectiontype = 4;
+ $rev = $2;
+ die "Revision mismatch: $line\n " unless $rev == $oldrev;
+ }
+ else
+ {
+ die "Internal parse error: $line\n ";
+ }
+ next LINE;
+ }
+
+ # Parse data
+ if ($sectiontype != 4)
+ {
+ # Key and value
+ if ($line =~ m"^(.*)=(.*)$")
+ {
+ my ($key, $value) = ($1, $2);
+ # Global configuration
+ if (1 == $sectiontype)
+ {
+ if ($key eq 'crlf')
+ {
+ $crlfmode = 1, next LINE if $value eq 'convert';
+ $crlfmode = 0, next LINE if $value eq 'none';
+ }
+ die "Unknown configuration option: $line\n ";
+ }
+ # Revision specification
+ if (2 == $sectiontype)
+ {
+ my $current = $revmap{$rev};
+ $author{$current} = $value, next LINE if $key eq 'author';
+ $branch{$current} = $value, next LINE if $key eq 'branch';
+ $parent{$current} = $value, next LINE if $key eq 'parent';
+ $timesource{$current} = $value, next LINE if $key eq 'timestamp';
+ push(@{$merges{$current}}, $value), next LINE if $key eq 'merges';
+ die "Unknown revision option: $line\n ";
+ }
+ # Filespecs
+ if (3 == $sectiontype)
+ {
+ # Add the file and create a marker
+ die "File not found: $line\n " unless -f $value;
+ my $current = $revmap{$rev};
+ ${$files{$current}}{$key} = $mark;
+ my $time = &fileblob($value, $crlfmode, $mark ++);
+
+ # Update revision timestamp if more recent than other
+ # files seen, or if this is the file we have selected
+ # to take the time stamp from using the "timestamp"
+ # directive.
+ if ((defined $timesource{$current} && $timesource{$current} eq $value)
+ || $time > $time{$current})
+ {
+ $time{$current} = $time;
+ }
+ }
+ }
+ else
+ {
+ die "Parse error: $line\n ";
+ }
+ }
+ else
+ {
+ # Commit message
+ my $current = $revmap{$rev};
+ if (defined $message{$current})
+ {
+ $message{$current} .= "\n";
+ }
+ $message{$current} .= $line;
+ }
+}
+close CFG;
+
+# Start spewing out data for git-fast-import
+foreach my $commit (@revs)
+{
+ # Progress
+ print OUT "progress Creating revision $commit\n";
+
+ # Create commit header
+ my $mark = $revmap{$commit};
+
+ # Branch and commit id
+ print OUT "commit refs/heads/", $branch{$mark}, "\nmark :", $mark, "\n";
+
+ # Author and timestamp
+ die "No timestamp defined for $commit (no files?)\n" unless defined $time{$mark};
+ print OUT "committer ", $author{$mark}, " ", $time{$mark}, " +0100\n";
+
+ # Commit message
+ die "No message defined for $commit\n" unless defined $message{$mark};
+ my $message = $message{$mark};
+ $message =~ s/\n$//; # Kill trailing empty line
+ print OUT "data ", length($message), "\n", $message, "\n";
+
+ # Parent and any merges
+ print OUT "from :", $revmap{$parent{$mark}}, "\n" if defined $parent{$mark};
+ if (defined $merges{$mark})
+ {
+ foreach my $merge (@{$merges{$mark}})
+ {
+ print OUT "merge :", $revmap{$merge}, "\n";
+ }
+ }
+
+ # Output file marks
+ print OUT "deleteall\n"; # start from scratch
+ foreach my $file (sort keys %{$files{$mark}})
+ {
+ print OUT "M 644 :", ${$files{$mark}}{$file}, " $file\n";
+ }
+ print OUT "\n";
+}
+
+# Create one file blob
+sub fileblob
+{
+ my ($filename, $crlfmode, $mark) = @_;
+
+ # Import the file
+ print OUT "progress Importing $filename\nblob\nmark :$mark\n";
+ open FILE, '<', $filename or die "Cannot read $filename\n ";
+ binmode FILE;
+ my ($size, $mtime) = (stat(FILE))[7,9];
+ my $file;
+ read FILE, $file, $size;
+ close FILE;
+ $file =~ s/\r\n/\n/g if $crlfmode;
+ print OUT "data ", length($file), "\n", $file, "\n";
+
+ return $mtime;
+}
+
+__END__
+
+=pod
+
+=head1 EXAMPLES
+
+B<import-directories.perl> F<project.import>
+
+=head1 AUTHOR
+
+Copyright 2008-2009 Peter Krefting E<lt>peter@softwolves.pp.se>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation.
+
+=cut
--
1.6.3.3
^ permalink raw reply related
* Re: [PATCH] import-tars: Allow per-tar author and commit message.
From: Peter Krefting @ 2009-08-26 9:17 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Nanako Shiraishi, Sam Vilain, Git Mailing List
In-Reply-To: <7v8wh7pumr.fsf@alter.siamese.dyndns.org>
Junio C Hamano:
> And the switch could be "--metainfo=<ext>", so that people can choose to
> use other extensions, e.g. with "--metainfo=info" file.tar.info would be
> read for descriptions.
That's a good idea. I just made a simple "-m" switch to enable the new code.
I'll change it into a "--metainfo" and post an updated patch later.
--
\\// Peter - http://www.softwolves.pp.se/
^ permalink raw reply
* Newbie / git / gitosis question
From: Howard Miller @ 2009-08-26 9:27 UTC (permalink / raw)
To: git
I've been working away at Gitosis and it's mostly fair enough but
there's one bit that's unclear to me...
git push origin master:refs/heads/master
Would somebody kindly explain (or point to docs) what
refs/heads/master means? How is this different from just 'git push
origin master' or even 'git push origin master:master'?
Any insights much appreciated.
^ permalink raw reply
* Re: Newbie / git / gitosis question
From: Michael Wookey @ 2009-08-26 9:38 UTC (permalink / raw)
To: Howard Miller; +Cc: git
In-Reply-To: <26ae428a0908260227k7ac6aeden9a4eae7ee95d4d45@mail.gmail.com>
2009/8/26 Howard Miller <howard@e-learndesign.co.uk>:
> I've been working away at Gitosis and it's mostly fair enough but
> there's one bit that's unclear to me...
>
> git push origin master:refs/heads/master
>
> Would somebody kindly explain (or point to docs) what
> refs/heads/master means? How is this different from just 'git push
> origin master' or even 'git push origin master:master'?
>
> Any insights much appreciated.
You might find some insight here - http://progit.org/book/ch9-5.html
^ permalink raw reply
* Re: Newbie / git / gitosis question
From: Howard Miller @ 2009-08-26 9:46 UTC (permalink / raw)
To: Michael Wookey; +Cc: git
In-Reply-To: <d2e97e800908260238p28bd6d27o6377f395df32b03c@mail.gmail.com>
Mmm...
I think I see what's happening - vaguely - but I'm not sure I understand why!
Why does gitosis require you to be this specific? Why can't I just do
a 'straight' push?
Howard
2009/8/26 Michael Wookey <michaelwookey@gmail.com>:
> 2009/8/26 Howard Miller <howard@e-learndesign.co.uk>:
>> I've been working away at Gitosis and it's mostly fair enough but
>> there's one bit that's unclear to me...
>>
>> git push origin master:refs/heads/master
>>
>> Would somebody kindly explain (or point to docs) what
>> refs/heads/master means? How is this different from just 'git push
>> origin master' or even 'git push origin master:master'?
>>
>> Any insights much appreciated.
>
> You might find some insight here - http://progit.org/book/ch9-5.html
>
^ permalink raw reply
* Re: [PATCH] upload-pack: add a trigger for post-upload-pack hook
From: Johannes Schindelin @ 2009-08-26 10:06 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, Tom Werner, Tom Preston-Werner, git
In-Reply-To: <7vr5uzeyl7.fsf@alter.siamese.dyndns.org>
Hi,
On Wed, 26 Aug 2009, Junio C Hamano wrote:
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
> > On Tue, 25 Aug 2009, Junio C Hamano wrote:
> >
> >> and if one of the primary reason for this new hook is statistics, it
> >> would be useful to see the number of bytes given, where the
> >> fetch-pack came from, and if we are using git-daemon virtual hosting
> >> which of our domain served the request.
> >
> > Certainly those are possible add-on patches, but would you require
> > them to be in the same commit?
>
> I was merely responding to the "what else would be useful" question posed
> by Peff.
Sure.
> Did you get an impression that I was saying "you must add these
> otherwise I'll reject the patch"?
Well, I got the impression that you'd not accept the patch without
additional information given by the hook, and I got the impression that
Tom would decide as a consequence to rather live with his eternal fork
instead of working on getting this patch included.
> It might make sense to define the external interface to be "information
> is given through the standard input of the hook, formatted in YAML, and
> here are the initial set of items that may be fed", so that we do not
> have to worry about the details too much.
Hmm. You bring up YAML a few times recently, it seems, but I think this
is not what you are meaning. In this case, you'd need to have a simple
enquiry system that asks for some information and receives it as a
response.
But I would find it utterly overengineered if upload-pack would support
something as complicated as that. IMHO either upload-pack knows already
about the information, or the script has to try to discover it using Git
commands itself.
My conclusion: I _think_ it would make sense to pass the name of the pack
file(s) created by upload-pack to the hook, or something similar, but
nothing more. Well, _maybe_ the byte count of the protocol exchange and
the IP. But nothing that requires calculations.
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH] git-bisect: call the found commit "*the* first bad commit"
From: Johannes Schindelin @ 2009-08-26 10:08 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Nanako Shiraishi, git
In-Reply-To: <7vfxbfeyh5.fsf@alter.siamese.dyndns.org>
Hi,
On Wed, 26 Aug 2009, Junio C Hamano wrote:
> Nanako Shiraishi <nanako3@lavabit.com> writes:
>
> > .. as we learned in the school ;-)
>
> Thanks.
>
> Is it "learned in school", or do you also need "*the*" there?
>
> ;-)
Well, I learnt at school that it is "learnt" and "at school"...
double ;-)
Ciao,
Dscho
^ permalink raw reply
* [RFC] Use a 16-tree instead of a 256-tree for storing notes
From: Johan Herland @ 2009-08-26 10:31 UTC (permalink / raw)
To: Johannes Schindelin
Cc: git, gitster, trast, tavestbo, git, chriscool, spearce
In-Reply-To: <200908010436.57480.johan@herland.net>
The 256-tree structure is considerably faster than storing all entries in a
hash_map. Also, the memory consumption of the 256-tree structure is lower
than the hash_map, provided that you're only loading a few notes from a
"properly fanned-out" notes tree (i.e. 100000 notes in a 2/2/36 structure).
However, in the worst case (loading all 100000 notes), the memory usage of
the 256-tree structure (62.64 MB) is significantly worse than the hash_map
approach (10.25 MB).
This patch modifies the 256-tree structure into a 16-tree structure. This
significantly improves the memory situation. The result uses less memory
than both the 256-tree structure, and the hash_map approach, with a worst
case usage of 8.54 MB. Additionally, it seems to slightly improve the
runtime performance as well (probably because of the improved memory usage).
In conclusion, this is faster and smaller than all the previous drafts.
$ ./test_performance.sh
Timing 100 reps of 'git log -n 10 refs/heads/master >/dev/null' at fanout level 0...
15.05user 1.44system 0:16.59elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+782490minor)pagefaults 0swaps
Timing 100 reps of 'git log -n 10 refs/heads/master >/dev/null' at fanout level 1...
0.68user 0.17system 0:00.87elapsed 98%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+99585minor)pagefaults 0swaps
Timing 100 reps of 'git log -n 10 refs/heads/master >/dev/null' at fanout level 2...
0.41user 0.17system 0:00.61elapsed 97%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+94084minor)pagefaults 0swaps
Signed-off-by: Johan Herland <johan@herland.net>
---
Hi,
This patch goes on top of the 256-tree RFC I sent earlier.
If nobody suggests further improvements, this patch will be
included in the next iteration of the jh/notes topic.
Have fun! :)
...Johan
notes.c | 26 ++++++++++++++------------
1 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/notes.c b/notes.c
index 9282b16..32b1e01 100644
--- a/notes.c
+++ b/notes.c
@@ -7,9 +7,9 @@
#include "tree-walk.h"
/*
- * Use a non-balancing simple 256-tree structure with struct int_node as
+ * Use a non-balancing simple 16-tree structure with struct int_node as
* internal nodes, and struct leaf_node as leaf nodes. Each int_node has a
- * 256-array of pointers to its children
+ * 16-array of pointers to its children
* The bottom 2 bits of each pointer is used to identify the pointer type
* - ptr & 3 == 0 - NULL pointer, assert(ptr == NULL)
* - ptr & 3 == 1 - pointer to next internal node - cast to struct int_node *
@@ -21,18 +21,18 @@
*
* To add a leaf_node:
* 1. Start at the root node, with n = 0
- * 2. Use the nth byte of the key as an index into a:
- * - If NULL, store the tweaked pointer directly into a[n]
- * - If an int_node, recurse into that node and increment n
- * - If a leaf_node:
+ * 2. Use the nth nibble of the key as an index into a:
+ * - If a[n] is NULL, store the tweaked pointer directly into a[n]
+ * - If a[n] is an int_node, recurse into that node and increment n
+ * - If a[n] is a leaf_node:
* 1. Check if they're equal, and handle that (abort? overwrite?)
* 2. Create a new int_node, and store both leaf_nodes there
* 3. Store the new int_node into a[n].
*
* To find a leaf_node:
* 1. Start at the root node, with n = 0
- * 2. Use the nth byte of the key as an index into a:
- * - If an int_node, recurse into that node and increment n
+ * 2. Use the nth nibble of the key as an index into a:
+ * - If a[n] is an int_node, recurse into that node and increment n
* - If a leaf_node with matching key, return leaf_node (assert note entry)
* - If a matching subtree entry, unpack that subtree entry (and remove it);
* restart search at the current level.
@@ -42,7 +42,7 @@
* subtree entry (and remove it); restart search at the current level.
*/
struct int_node {
- void *a[256];
+ void *a[16];
};
/*
@@ -79,11 +79,13 @@ static int initialized;
static void load_subtree(struct leaf_node *subtree, struct int_node *node,
unsigned int n);
+#define GET_NIBBLE(n, sha1) (((sha1[n >> 1]) >> ((n & 0x01) << 2)) & 0x0f)
+
static struct leaf_node *note_tree_find(struct int_node *tree, unsigned char n,
const unsigned char *key_sha1)
{
struct leaf_node *l;
- unsigned char i = key_sha1[n];
+ unsigned char i = GET_NIBBLE(n, key_sha1);
void *p = tree->a[i];
switch(GET_PTR_TYPE(p)) {
@@ -138,7 +140,7 @@ static int note_tree_insert(struct int_node *tree, unsigned char n,
struct int_node *new_node;
const struct leaf_node *l;
int ret;
- unsigned char i = entry->key_sha1[n];
+ unsigned char i = GET_NIBBLE(n, entry->key_sha1);
void *p = tree->a[i];
assert(GET_PTR_TYPE(entry) == PTR_TYPE_NULL);
switch(GET_PTR_TYPE(p)) {
@@ -211,7 +213,7 @@ static void load_subtree(struct leaf_node *subtree, struct int_node *node,
sha1_to_hex(subtree->val_sha1));
prefix_len = subtree->key_sha1[19];
- assert(prefix_len >= n);
+ assert(prefix_len * 2 >= n);
memcpy(commit_sha1, subtree->key_sha1, prefix_len);
while (tree_entry(&desc, &entry)) {
int len = get_sha1_hex_segment(entry.path, strlen(entry.path),
--
1.6.4.304.g1365c.dirty
^ permalink raw reply related
* Re: Linus' sha1 is much faster!
From: Pádraig Brady @ 2009-08-26 11:39 UTC (permalink / raw)
To: Nicolas Pitre
Cc: Linus Torvalds, John Tapsell, Bryan Donlan, Bug-coreutils,
Git Mailing List, Brandon Casey, Junio C Hamano, Paul Kocher
In-Reply-To: <alpine.LFD.2.00.0908162151180.6044@xanadu.home>
Nicolas Pitre wrote:
> On Sat, 15 Aug 2009, Linus Torvalds wrote:
>
>> (Heh. Looking at that, I probably should move the 'size' field first,
>> since that would have different alignment rules, and the struct would be
>> more tightly packed that way, and initialize better).
>
> I was about to suggest (i.e. post) a patch for that. This is indeed a
> good idea.
>
>> Afaik, none of the actual code remains (the mozilla SHA1 thing did the
>> wrong thing for performance even for just the final bytes, and did those a
>> byte at a time etc, so I rewrote even the trivial SHA1_Final parts).
>
> Maybe a patch adding a proper header with the actual license would be a
> good idea too.
So have you decided on a final licence,
and if so update the headers accordingly?
cheers!
Pádraig.
^ permalink raw reply
* Re: Newbie / git / gitosis question
From: Graham Perks @ 2009-08-26 11:54 UTC (permalink / raw)
To: Howard Miller; +Cc: git
In-Reply-To: <26ae428a0908260227k7ac6aeden9a4eae7ee95d4d45@mail.gmail.com>
On Aug 26, 2009, at 4:27 AM, Howard Miller wrote:
> there's one bit that's unclear to me...
>
> git push origin master:refs/heads/master
>
> Would somebody kindly explain (or point to docs) what
> refs/heads/master means?
I wish somehow these refs would be hidden so newbies like me and
everyone I introduce to git didn't have to know about them. They feel
like an "advanced concept", some internal syntax that 99% of users
shouldn't need to know about. When I see a refspec in the help pages
my eyes glaze over!
Graham.
^ permalink raw reply
* Re: [RFC] Use a 16-tree instead of a 256-tree for storing notes
From: Alex Riesen @ 2009-08-26 12:05 UTC (permalink / raw)
To: Johan Herland
Cc: Johannes Schindelin, git, gitster, trast, tavestbo, git,
chriscool, spearce
In-Reply-To: <200908261231.01616.johan@herland.net>
On Wed, Aug 26, 2009 at 12:31, Johan Herland<johan@herland.net> wrote:
> The 256-tree structure is considerably faster than storing all entries in a
This part is confusing. Was 256-tree better (as in "faster") then?
> hash_map. Also, the memory consumption of the 256-tree structure is lower
> than the hash_map, provided that you're only loading a few notes from a
> "properly fanned-out" notes tree (i.e. 100000 notes in a 2/2/36 structure).
> However, in the worst case (loading all 100000 notes), the memory usage of
> the 256-tree structure (62.64 MB) is significantly worse than the hash_map
> approach (10.25 MB).
>
> This patch modifies the 256-tree structure into a 16-tree structure. This
> significantly improves the memory situation. The result uses less memory
> than both the 256-tree structure, and the hash_map approach, with a worst
> case usage of 8.54 MB. Additionally, it seems to slightly improve the
> runtime performance as well (probably because of the improved memory usage).
^ permalink raw reply
* Re: [PATCH] git-bisect: call the found commit "*the* first bad commit"
From: Alex Riesen @ 2009-08-26 12:10 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Junio C Hamano, Nanako Shiraishi, git
In-Reply-To: <alpine.DEB.1.00.0908261207400.4713@intel-tinevez-2-302>
On Wed, Aug 26, 2009 at 12:08, Johannes
Schindelin<Johannes.Schindelin@gmx.de> wrote:
> On Wed, 26 Aug 2009, Junio C Hamano wrote:
>> Nanako Shiraishi <nanako3@lavabit.com> writes:
>>
>> > .. as we learned in the school ;-)
>>
>> Thanks.
>>
>> Is it "learned in school", or do you also need "*the*" there?
>>
>> ;-)
>
> Well, I learnt at school that it is "learnt" and "at school"...
>
> double ;-)
There is not one native speaker in this discussion, BTW :)
http://www.thefreedictionary.com/learn
http://www.thefreedictionary.com/school (look for American
in "Translation")
^ permalink raw reply
* Re: [PATCH] Add option -b/--branch to clone for select a new HEAD
From: Björn Steinbrink @ 2009-08-26 12:16 UTC (permalink / raw)
To: Kirill A. Korinskiy; +Cc: gitster, git
In-Reply-To: <87ljl694fd.wl%catap@catap.ru>
On 2009.08.26 15:53:58 +0400, Kirill A. Korinskiy wrote:
> At Wed, 26 Aug 2009 00:36:37 +0200,
> Björn Steinbrink <B.Steinbrink@gmx.de> wrote:
>
>
> > > @@ -518,7 +521,21 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
> > >
> > > mapped_refs = write_remote_refs(refs, refspec, reflog_msg.buf);
> > >
> > > - remote_head = find_ref_by_name(refs, "HEAD");
> > > + if (option_branch) {
> > > + strbuf_addf(&branch_head, "%s%s", src_ref_prefix, option_branch);
> > > +
> > > + remote_head = find_ref_by_name(refs, branch_head.buf);
> > > + }
> > > +
> > > + if (!remote_head) {
> > > + if (option_branch)
> > > + warning("Remote branch %s not found in upstream %s"
> > > + ", using HEAD instead",
> > > + option_branch, option_origin);
> > > +
> > > + remote_head = find_ref_by_name(refs, "HEAD");
> > > + }
> > > +
> > > head_points_at = guess_remote_head(remote_head, mapped_refs, 0);
> >
> > This would still pick refs/heads/master if refs/heads/master and
> > refs/heads/<branch> reference the same commit. That's due to the check
> > in guess_remote_head() which prefers refs/heads/master over all other
> > refs. While this is acceptable for the HEAD lookup, I'd treat that as a
> > bug for this new option.
> >
>
> My english is not a good and I don't understand it, sorry.
guess_remote_head() compares the object ids from remote_head and all of
the remote's refs to guess which is the right one.
Let's say that the repo has:
refs/heads/master: object1
refs/heads/foo: object2
refs/heads/bar: object1
If you do "git clone -b foo ...", then remote_head->old_sha1 will be
"object2". guess_remote_head() compares that to all the remote heads. In
this case, it will find refs/heads/foo (as expected).
But when you do "git clone -b bar", then remote_head->old_sha1 will be
"object1". And guess_remote_head() will then take refs/heads/master,
as it prefers that one.
doener@atjola:h $ mkdir a; cd a; git init
Initialized empty Git repository in /home/doener/h/a/.git/
doener@atjola:a (master) $ git commit --allow-empty -m init
[master (root-commit) a7a0b54] init
doener@atjola:a (master) $ git branch bar
doener@atjola:a (master) $ git checkout -b foo
Switched to a new branch 'foo'
doener@atjola:a (foo) $ git commit --allow-empty -m on_foo
[foo 375047e] on_foo
doener@atjola:a (foo) $ cd ..
doener@atjola:h $ (git clone -b foo a foo; cd foo; git branch)
Initialized empty Git repository in /home/doener/h/foo/.git/
* foo
doener@atjola:h $ (git clone -b bar a bar; cd bar; git branch)
Initialized empty Git repository in /home/doener/h/bar/.git/
* master
That said, I actually wonder why you don't simple set HEAD in the
original repo so that you get whichever branch you want by default
anyway.
Björn
^ permalink raw reply
* Re: git clone http://git.savannah.gnu.org/cgit/xboard.git segfaults
From: Tay Ray Chuan @ 2009-08-26 12:20 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Ali Polatel, git
In-Reply-To: <alpine.DEB.1.00.0908171620160.4991@intel-tinevez-2-302>
Hi,
On Mon, Aug 17, 2009 at 10:22 PM, Johannes Schindelin<Johannes.Schindelin@gmx.de> wrote:
> Seems that an object request is aborted, but the slot, and therefore the
> callback, is called nevertheless. Tay, does that ring a bell?
thanks Johannes, your diagnosis was a vital clue.
Ali, could you see if this patch fixes it for you? On my side, I had
some difficulty reproducing your problem reliably (it happened
sometimes but not on other times).
--
Cheers,
Ray Chuan
-- >8 --
Subject: [PATCH] http.c: set slot callback members to NULL when releasing object
Set the members callback_func and callback_data of freq->slot to NULL
when releasing a http_object_request. release_active_slot() is also
invoked on the slot to remove the curl handle associated with the slot
from the multi stack (CURLM *curlm in http.c).
These prevent the callback function and data from being used in http
methods (like http.c::finish_active_slot()) after a
http_object_request has been free'd.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
---
http.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/http.c b/http.c
index a2720d5..1ae19e0 100644
--- a/http.c
+++ b/http.c
-1285,5 +1285,10 @@ void release_http_object_request(struct http_object_request *freq)
free(freq->url);
freq->url = NULL;
}
- freq->slot = NULL;
+ if (freq->slot != NULL) {
+ freq->slot->callback_func = NULL;
+ freq->slot->callback_data = NULL;
+ release_active_slot(freq->slot);
+ freq->slot = NULL;
+ }
}
--
1.6.4.193.gaceaa.dirty
^ permalink raw reply
* Re: [RFC] Use a 16-tree instead of a 256-tree for storing notes
From: Johan Herland @ 2009-08-26 12:56 UTC (permalink / raw)
To: Alex Riesen
Cc: Johannes Schindelin, git, gitster, trast, tavestbo, git,
chriscool, spearce
In-Reply-To: <81b0412b0908260505m233d9a5cmefdd81e1ef51a299@mail.gmail.com>
On Wednesday 26 August 2009, Alex Riesen wrote:
> On Wed, Aug 26, 2009 at 12:31, Johan Herland<johan@herland.net> wrote:
> > The 256-tree structure is considerably faster than storing all
> > entries in a
>
> This part is confusing. Was 256-tree better (as in "faster") then?
256-tree is faster than the everything-in-hash_map draft.
16-tree is slightly faster than 256-tree
256-tree uses more memory (in the worst case) that the
everything-in-hash-map draft.
16-tree uses less memory than both.
Makes sense?
...Johan
--
Johan Herland, <johan@herland.net>
www.herland.net
^ permalink raw reply
* Re: git clone http://git.savannah.gnu.org/cgit/xboard.git segfaults
From: Ali Polatel @ 2009-08-26 13:12 UTC (permalink / raw)
To: Tay Ray Chuan; +Cc: git
In-Reply-To: <20090826202053.6e6442a6.rctay89@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 609 bytes --]
Tay Ray Chuan yazmış:
> Hi,
>
> On Mon, Aug 17, 2009 at 10:22 PM, Johannes Schindelin<Johannes.Schindelin@gmx.de> wrote:
> > Seems that an object request is aborted, but the slot, and therefore the
> > callback, is called nevertheless. Tay, does that ring a bell?
>
> thanks Johannes, your diagnosis was a vital clue.
>
> Ali, could you see if this patch fixes it for you? On my side, I had
> some difficulty reproducing your problem reliably (it happened
> sometimes but not on other times).
>
It works, I don't get any segfaults after applying this patch.
--
Regards,
Ali Polatel
[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* Re: [RFC] Use a 16-tree instead of a 256-tree for storing notes
From: Alex Riesen @ 2009-08-26 13:24 UTC (permalink / raw)
To: Johan Herland
Cc: Johannes Schindelin, git, gitster, trast, tavestbo, git,
chriscool, spearce
In-Reply-To: <200908261456.55906.johan@herland.net>
On Wed, Aug 26, 2009 at 14:56, Johan Herland<johan@herland.net> wrote:
> On Wednesday 26 August 2009, Alex Riesen wrote:
>> On Wed, Aug 26, 2009 at 12:31, Johan Herland<johan@herland.net> wrote:
>> > The 256-tree structure is considerably faster than storing all
>> > entries in a
>>
>> This part is confusing. Was 256-tree better (as in "faster") then?
>
> 256-tree is faster than the everything-in-hash_map draft.
> 16-tree is slightly faster than 256-tree
>
> 256-tree uses more memory (in the worst case) that the
> everything-in-hash-map draft.
> 16-tree uses less memory than both.
>
> Makes sense?
Oh, it does, it is just confusingly presented. How about:
The 16-tree is both faster and has lower footprint then 256-tree
code, which in its turn is noticably faster and smaller then existing
hash_map implementation. ...
^ permalink raw reply
* Re: [RFC] Use a 16-tree instead of a 256-tree for storing notes
From: Andreas Ericsson @ 2009-08-26 13:27 UTC (permalink / raw)
To: Alex Riesen
Cc: Johan Herland, Johannes Schindelin, git, gitster, trast, tavestbo,
git, chriscool, spearce
In-Reply-To: <81b0412b0908260624v30d32cc1m96e798076b51cbc9@mail.gmail.com>
Alex Riesen wrote:
> On Wed, Aug 26, 2009 at 14:56, Johan Herland<johan@herland.net> wrote:
>> On Wednesday 26 August 2009, Alex Riesen wrote:
>>> On Wed, Aug 26, 2009 at 12:31, Johan Herland<johan@herland.net> wrote:
>>>> The 256-tree structure is considerably faster than storing all
>>>> entries in a
>>> This part is confusing. Was 256-tree better (as in "faster") then?
>> 256-tree is faster than the everything-in-hash_map draft.
>> 16-tree is slightly faster than 256-tree
>>
>> 256-tree uses more memory (in the worst case) that the
>> everything-in-hash-map draft.
>> 16-tree uses less memory than both.
>>
>> Makes sense?
>
> Oh, it does, it is just confusingly presented. How about:
>
> The 16-tree is both faster and has lower footprint then 256-tree
> code, which in its turn is noticably faster and smaller then existing
> hash_map implementation. ...
If it's to be squashed in, why mention the 256-tree at all (except
for possibly as something to compare with at the end)?
If it goes on top, why mention the hash_map at all?
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
Considering the successes of the wars on alcohol, poverty, drugs and
terror, I think we should give some serious thought to declaring war
on peace.
^ permalink raw reply
* [PATCH] Minor improvement to the write-tree documentation
From: David Kågedal @ 2009-08-26 14:04 UTC (permalink / raw)
To: git; +Cc: David Kågedal
Signed-off-by: David Kågedal <davidk@lysator.liu.se>
---
Documentation/git-write-tree.txt | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/Documentation/git-write-tree.txt b/Documentation/git-write-tree.txt
index 26d3850..3eee11f 100644
--- a/Documentation/git-write-tree.txt
+++ b/Documentation/git-write-tree.txt
@@ -12,7 +12,8 @@ SYNOPSIS
DESCRIPTION
-----------
-Creates a tree object using the current index.
+Creates a tree object using the current index. The sha1 of the new
+tree object is printed to standard output.
The index must be in a fully merged state.
--
1.6.4.rc3.21.g3b9e
^ permalink raw reply related
* Re: [PATCH] upload-pack: add a trigger for post-upload-pack hook
From: Jeff King @ 2009-08-26 14:19 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Junio C Hamano, Tom Werner, Tom Preston-Werner, git
In-Reply-To: <alpine.DEB.1.00.0908261200160.4713@intel-tinevez-2-302>
On Wed, Aug 26, 2009 at 12:06:59PM +0200, Johannes Schindelin wrote:
> > Did you get an impression that I was saying "you must add these
> > otherwise I'll reject the patch"?
>
> Well, I got the impression that you'd not accept the patch without
> additional information given by the hook, and I got the impression that
> Tom would decide as a consequence to rather live with his eternal fork
> instead of working on getting this patch included.
I don't think any of us wants that. My point in bringing it up at all
was just "is there anything obvious that we should be adding before this
makes it into master, because after that we will have to deal with an
interface change". I certainly don't want to delay a useful patch too
much while we wait for the moon.
-Peff
^ permalink raw reply
* Re: git+http:// proof-of-concept (not using CONNECT)
From: Douglas Campos @ 2009-08-26 14:34 UTC (permalink / raw)
To: Eric Wong; +Cc: Tony Finch, Constantine Plotnikov, git
In-Reply-To: <20090707205003.GA31195@dcvr.yhbt.net>
Any news about this approach? I've heard some noise about a CGI
implementation....
--
Douglas Campos
qmx.me
^ permalink raw reply
* Re: [RFC] Use a 16-tree instead of a 256-tree for storing notes
From: Johan Herland @ 2009-08-26 14:43 UTC (permalink / raw)
To: Andreas Ericsson
Cc: Alex Riesen, Johannes Schindelin, git, gitster, trast, tavestbo,
git, chriscool, spearce
In-Reply-To: <4A95383A.4080104@op5.se>
On Wednesday 26 August 2009, Andreas Ericsson wrote:
> Alex Riesen wrote:
> > On Wed, Aug 26, 2009 at 14:56, Johan Herland<johan@herland.net>
wrote:
> >> On Wednesday 26 August 2009, Alex Riesen wrote:
> >>> On Wed, Aug 26, 2009 at 12:31, Johan Herland<johan@herland.net>
wrote:
> >>>> The 256-tree structure is considerably faster than storing all
> >>>> entries in a
> >>>
> >>> This part is confusing. Was 256-tree better (as in "faster")
> >>> then?
> >>
> >> 256-tree is faster than the everything-in-hash_map draft.
> >> 16-tree is slightly faster than 256-tree
> >>
> >> 256-tree uses more memory (in the worst case) that the
> >> everything-in-hash-map draft.
> >> 16-tree uses less memory than both.
> >>
> >> Makes sense?
> >
> > Oh, it does, it is just confusingly presented. How about:
> >
> > The 16-tree is both faster and has lower footprint then 256-tree
> > code, which in its turn is noticably faster and smaller then
> > existing hash_map implementation. ...
>
> If it's to be squashed in, why mention the 256-tree at all (except
> for possibly as something to compare with at the end)?
> If it goes on top, why mention the hash_map at all?
Ah. Sorry for the confusion. These patches are not meant to standalone
patches in the jh/notes series. They just compare various solutions to
the problem of parsing a notes tree structure with fanout in an
efficient manner.
The next iteration of the jh/notes series will include the preferred
solution (16-tree unless something better shows up), _without_ talking
about the differences between alternative solutions. As such the
hash_map and 256-tree will not be mentioned at all.
...Johan
--
Johan Herland, <johan@herland.net>
www.herland.net
^ permalink raw reply
* [PATCH] Add option -b/--branch to clone for select a new HEAD
From: Kirill A. Korinskiy @ 2009-08-26 14:46 UTC (permalink / raw)
To: B.Steinbrink; +Cc: git, Kirill A. Korinskiy
In-Reply-To: <20090826121600.GA29098@atjola.homenet>
Sometimes (especially on production systems) we need to use only one
remote branch for building software. It's really annoying to clone
origin and then switch branch by hand everytime. So this patch
provides functionality to clone a remote branch with one command
without using checkout after clone.
Signed-off-by: Kirill A. Korinskiy <catap@catap.ru>
---
Documentation/git-clone.txt | 5 ++++
builtin-clone.c | 25 ++++++++++++++++++---
t/t5706-clone-branch.sh | 49 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 75 insertions(+), 4 deletions(-)
create mode 100755 t/t5706-clone-branch.sh
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 2c63a0f..5cd106c 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -127,6 +127,11 @@ objects from the source repository into a pack in the cloned repository.
Instead of using the remote name 'origin' to keep track
of the upstream repository, use <name>.
+--branch <name>::
+-b <name>::
+ Create a local branch head for <name> instead of the branch
+ referenced by the remote repos HEAD.
+
--upload-pack <upload-pack>::
-u <upload-pack>::
When given, and the repository to clone from is accessed
diff --git a/builtin-clone.c b/builtin-clone.c
index 32dea74..91392a3 100644
--- a/builtin-clone.c
+++ b/builtin-clone.c
@@ -41,6 +41,7 @@ static int option_quiet, option_no_checkout, option_bare, option_mirror;
static int option_local, option_no_hardlinks, option_shared;
static char *option_template, *option_reference, *option_depth;
static char *option_origin = NULL;
+static char *option_branch = NULL;
static char *option_upload_pack = "git-upload-pack";
static int option_verbose;
@@ -65,6 +66,8 @@ static struct option builtin_clone_options[] = {
"reference repository"),
OPT_STRING('o', "origin", &option_origin, "branch",
"use <branch> instead of 'origin' to track upstream"),
+ OPT_STRING('b', "branch", &option_branch, "branch",
+ "use <branch> from upstream as HEAD"),
OPT_STRING('u', "upload-pack", &option_upload_pack, "path",
"path to git-upload-pack on the remote"),
OPT_STRING(0, "depth", &option_depth, "depth",
@@ -347,8 +350,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
const char *repo_name, *repo, *work_tree, *git_dir;
char *path, *dir;
int dest_exists;
- const struct ref *refs, *head_points_at, *remote_head, *mapped_refs;
- struct strbuf key = STRBUF_INIT, value = STRBUF_INIT;
+ const struct ref *refs, *head_points_at, *remote_head = NULL, *mapped_refs;
+ struct strbuf key = STRBUF_INIT, value = STRBUF_INIT, branch_head = STRBUF_INIT;
struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT;
struct transport *transport = NULL;
char *src_ref_prefix = "refs/heads/";
@@ -518,8 +521,22 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
mapped_refs = write_remote_refs(refs, refspec, reflog_msg.buf);
- remote_head = find_ref_by_name(refs, "HEAD");
- head_points_at = guess_remote_head(remote_head, mapped_refs, 0);
+ if (option_branch) {
+ strbuf_addf(&branch_head, "%s%s", src_ref_prefix, option_branch);
+
+ remote_head = find_ref_by_name(refs, branch_head.buf);
+ }
+
+ if (!remote_head) {
+ if (option_branch)
+ warning("Remote branch %s not found in upstream %s"
+ ", using HEAD instead",
+ option_branch, option_origin);
+
+ remote_head = find_ref_by_name(refs, "HEAD");
+ }
+
+ head_points_at = guess_remote_head(remote_head, mapped_refs, 1);
}
else {
warning("You appear to have cloned an empty repository.");
diff --git a/t/t5706-clone-branch.sh b/t/t5706-clone-branch.sh
new file mode 100755
index 0000000..b5fec50
--- /dev/null
+++ b/t/t5706-clone-branch.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+test_description='branch clone options'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+
+ mkdir parent &&
+ (cd parent && git init &&
+ echo one >file && git add file &&
+ git commit -m one && git branch foo &&
+ git checkout -b two &&
+ echo two >f && git add f && git commit -m two &&
+ git checkout master)
+
+'
+
+test_expect_success 'clone' '
+
+ git clone parent clone &&
+ (cd clone &&
+ test $(git rev-parse --verify HEAD) = \
+ $(git rev-parse --verify refs/remotes/origin/master) &&
+ test $(git rev-parse --verify HEAD) != \
+ $(git rev-parse --verify refs/remotes/origin/two))
+
+
+'
+
+test_expect_success 'clone -b two' '
+
+ git clone -b two parent clone-b &&
+ (cd clone-b &&
+ test $(git rev-parse --verify HEAD) = \
+ $(git rev-parse --verify refs/remotes/origin/two) &&
+ test $(git rev-parse --verify HEAD) != \
+ $(git rev-parse --verify refs/remotes/origin/master))
+
+'
+
+test_expect_success 'clone -b foo' '
+
+ git clone -b foo parent clone-b-foo &&
+ (cd clone-b-foo &&
+ test $(git branch | grep \* | sed -e s:\*\ ::) = foo)
+
+'
+
+test_done
--
1.6.2
^ permalink raw reply related
* Re: [PATCH] git-bisect: call the found commit "*the* first bad commit"
From: Jeff King @ 2009-08-26 15:29 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Junio C Hamano, Nanako Shiraishi, git
In-Reply-To: <alpine.DEB.1.00.0908261207400.4713@intel-tinevez-2-302>
On Wed, Aug 26, 2009 at 12:08:11PM +0200, Johannes Schindelin wrote:
> Well, I learnt at school that it is "learnt" and "at school"...
>
> double ;-)
Bloody Europeans. ;)
-Peff
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox