* Re: [PATCh] jit-trackdown
From: Junio C Hamano @ 2005-04-29 18:47 UTC (permalink / raw)
To: David Greaves; +Cc: GIT Mailing Lists
In-Reply-To: <42725AB8.5090501@dgreaves.com>
>>>>> "DG" == David Greaves <david@dgreaves.com> writes:
DG> Should really be cg-trackdown
Thanks for your kind words and the patch.
head="$1"
+if [ $head == "HEAD" ]; then
+ head=$(cat .git/HEAD)
+elif [ -f .git/refs/tags/$head ]; then
+ head=$(cat .git/refs/tags/$head)
+elif [ -f .git/refs/heads/$head ]; then
+ head=$(cat .git/refs/heads/$head)
+fi
+
I have been primarily looking at the plumbing side and not the
toilet side, and I still have not grokked cg-* yet. That's why
I did not do the right thing with these .git/refs/* stuff. If
this were to become part of cg-* suite, I would recommend just
using $(commit-id) there, which should be the only one that
needs to know the .git/* structure convention.
Have toilet side gitters reached a concensus (or semi-concensus)
on how things under .git/ should be organized? Is there a
summary somewhere, something along the following lines?
In subdirectories under $GIT_PROJECT_TOP/.git, you have
files that have some special meaning to the Cogito layer.
These files are all 41-byte long, which stores a 40-byte
SHA1 with terminating newline. What is stored in each
location is as follows:
.git/HEAD Head commit object of the
current tree.
.git/refs/heads/$ext Head commit object of the
external tree $ext. [*Q1*]
.git/refs/tags/$tag Named Tag object. [*Q2*]
*Q1* What is the syntax and semantics rule for $ext, like
"$ext matches '^[-A-Za-z0-9_]$' and is one of the
entries in .git/remotes"?
*Q2* What is the syntax and semantics rule for $tag, like
"$tag matches '^[-A-Za-z0-9_]$' and can be anything not
just commit"?
^ permalink raw reply
* Re: Mercurial 0.4b vs git patchbomb benchmark
From: Sean @ 2005-04-29 18:33 UTC (permalink / raw)
To: Tom Lord; +Cc: torvalds, mpm, linux-kernel, git
In-Reply-To: <200504291808.LAA25870@emf.net>
On Fri, April 29, 2005 2:08 pm, Tom Lord said:
> The confusion here is that you are talking about computational complexity
> while I am talking about complexity measured in hours of labor.
>
> You are assuming that the programmer generating the signature blindly
> trusts the tool to generate the signed document accurately. I am
> saying that it should be tractable for human beings to read the documents
> they are going to sign.
Developers obviously _do_ read the changes they submit to a project or
they would lose their trusted status. That has absolutely nothing to do
with signing, it's the exact same way things work today, without sigs.
It's not "blind trust" to expect a script to reproducibly sign documents
you've decided to submit to a project. The signature is not a QUALITY
guarantee in and of itself. It doesn't mean you have any additional
responsibility to remove all bugs before submitting. Conversely, not
signing something doesn't mean you can submit crap.
See? Signing something does not change the quality guarantee one way or
the other. It does not put any additional demands on the developer, so
it's fine to have an automated script do it. It's just a way to avoid
impersonations.
Sean
^ permalink raw reply
* [PATCH] GIT: Honour SHA1_FILE_DIRECTORY env var in git-pull-script
From: Rene Scharfe @ 2005-04-29 18:31 UTC (permalink / raw)
To: Linux Torvalds; +Cc: git
If you set SHA1_FILE_DIRECTORY to something else than .git/objects
git-pull-script will store the fetched files in a location the rest of
the tools does not expect.
git-prune-script also ignores this setting, but I think this is good,
because pruning a shared tree to fit a single project means throwing
away a lot of useful data. :-)
Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
commit 6fef2965444a6509d11a79bd33842125034dcec0
tree 63e9cdf5ff724bf462d9dc408b9c951985d4cecf
parent db413479f1bb0dabfc613b2b0017ca74aeb5a919
author Rene Scharfe <rene.scharfe@lsrfire.ath.cx> 1114799335 +0200
committer Rene Scharfe <rene.scharfe@lsrfire.ath.cx> 1114799335 +0200
Index: git-pull-script
===================================================================
--- 1e2168c7d554a4fbd25a09bb591ae0f82dac6513/git-pull-script (mode:100755 sha1:5111da98e68f4c3eb44499d20a210966dd445212)
+++ 63e9cdf5ff724bf462d9dc408b9c951985d4cecf/git-pull-script (mode:100755 sha1:0198c4805db7c2b78cd4424634873b0a86ee4107)
@@ -9,7 +9,7 @@
cp .git/HEAD .git/ORIG_HEAD
echo "Getting object database"
-rsync -avz --ignore-existing $merge_repo/objects/. .git/objects/.
+rsync -avz --ignore-existing $merge_repo/objects/. ${SHA1_FILE_DIRECTORY:-.git/objects}/.
echo "Getting remote head"
rsync -L $merge_repo/HEAD .git/MERGE_HEAD || exit 1
^ permalink raw reply
* Re: More problems...
From: Petr Baudis @ 2005-04-29 18:27 UTC (permalink / raw)
To: Russell King; +Cc: git
In-Reply-To: <20050429170127.A30010@flint.arm.linux.org.uk>
Dear diary, on Fri, Apr 29, 2005 at 06:01:27PM CEST, I got a letter
where Russell King <rmk@arm.linux.org.uk> told me that...
> rmk@dyn-67:[linux-2.6-rmk]:<1049> cg-update origin
> `../linux-2.6/.git/objects/00/78aeb85737197a84af1eeb0353dbef74427901' -> `.git/objects/00/78aeb85737197a84af1eeb0353dbef74427901'
> cp: cannot create link `.git/objects/00/78aeb85737197a84af1eeb0353dbef74427901': File exists
>
> By that time, the object files in the reference tree appear to have
> a newer timestamp than the corresponding ones in my local tree, and
> cp -lua fails.
I'm now away ,unfortunately, and no immediate idea stems to my mind on
how to fix it. Ideas welcomed - I need to hardlink missing entries from
one tree to another; it would be enough to be able to just tell cp to
ignore already present files.
Could you please try to give cp the -f flag?
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor
^ permalink raw reply
* Re: Odd decision of git-pasky-0.7 to do a merge
From: Petr Baudis @ 2005-04-29 18:21 UTC (permalink / raw)
To: Russell King; +Cc: git
In-Reply-To: <20050429103059.A3260@flint.arm.linux.org.uk>
Dear diary, on Fri, Apr 29, 2005 at 11:31:00AM CEST, I got a letter
where Russell King <rmk@arm.linux.org.uk> told me that...
> On Fri, Apr 29, 2005 at 10:07:17AM +0100, Russell King wrote:
> > rmk@hera:/pub/scm/linux/kernel/git/torvalds/linux-2.6.git(0)$ SHA1_FILE_DIRECTORY=./objects merge-base c60c390620e0abb60d4ae8c43583714bda27763f bdceb6a0162274934386f19f3ea5a9d44feb0b20
> > bdceb6a0162274934386f19f3ea5a9d44feb0b20
> >
> > $ merge-base c60c390620e0abb60d4ae8c43583714bda27763f bdceb6a0162274934386f19f3ea5a9d44feb0b20
> > e8108c98dd6d65613fa0ec9d2300f89c48d554bf
>
> This is the problem. It seems that merge-base in git-pasky-0.7
> doesn't work correctly.
I'm not sure if the merge-base in git-pasky-0.7 isn't the old one yet.
We replaced it with a date-based one since the old one *was* giving bad
results.
So, what about cogito-0.8?
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor
^ permalink raw reply
* Re: Mercurial 0.4b vs git patchbomb benchmark
From: Tom Lord @ 2005-04-29 18:08 UTC (permalink / raw)
To: torvalds; +Cc: mpm, seanlkml, linux-kernel, git
In-Reply-To: <Pine.LNX.4.58.0504291051460.18901@ppc970.osdl.org>
From: Linus Torvalds <torvalds@osdl.org>
On Fri, 29 Apr 2005, Tom Lord wrote:
>
> 1) the ancestry of their modified tree
>
> 2) the complete contents of their modified tree
>
> 3) input data for a patching program (let's call it "PATCH")
> which, at the very least, satisfies the equation:
>
> MOD_TREE = PATCH (this_diff, ORIG_TREE)
>
> On the other hand, signing documents which represent a {(1),(3)} pair
> with robust accuracy is, in most cases, much much less expensive than
> signing {(1),(2)} pairs with robust accuracy.
Not so.
It may be less expensive in your world, but that's the whole point of git:
it's _not_ less expensive in the git world.
In the git world, 1 and 2 aren't even separate things. They go together.
And you just sign it. End of story. It's so cheap to sign that it's not
even funny.
The confusion here is that you are talking about computational complexity
while I am talking about complexity measured in hours of labor.
You are assuming that the programmer generating the signature blindly
trusts the tool to generate the signed document accurately. I am
saying that it should be tractable for human beings to read the documents
they are going to sign.
More importantly, signing 3 is meaningless. 3 only makes sense with a
known starting point. You should never sign a patch without also saying
what you're patching.
I advocated signing a {(1),(3)} pair, not simply (3).
And once you do that, 1+2 and 1+3 are _exactly_ the same thing.
I already spoke to that.
And since git always works on the 1+2 level, it would be inexcusably
stupid to sign anything but that. 3 doesn't even exist per se, although
it's obviously fully defined by 1+2.
So I don't see your point. You complain about git signing, but you
complain on grounds that do not _exist_ in git, and then your alternative
(1+3) which is senseless in a git world doesn't actually end up being
anything really different - just more expensive.
I'm not sure what to suggest other than go back and read more carefully.
-t
^ permalink raw reply
* Re: Mercurial 0.4b vs git patchbomb benchmark
From: Linus Torvalds @ 2005-04-29 17:56 UTC (permalink / raw)
To: Tom Lord; +Cc: mpm, seanlkml, linux-kernel, git
In-Reply-To: <200504291734.KAA25263@emf.net>
On Fri, 29 Apr 2005, Tom Lord wrote:
>
> 1) the ancestry of their modified tree
>
> 2) the complete contents of their modified tree
>
> 3) input data for a patching program (let's call it "PATCH")
> which, at the very least, satisfies the equation:
>
> MOD_TREE = PATCH (this_diff, ORIG_TREE)
>
> On the other hand, signing documents which represent a {(1),(3)} pair
> with robust accuracy is, in most cases, much much less expensive than
> signing {(1),(2)} pairs with robust accuracy.
Not so.
It may be less expensive in your world, but that's the whole point of git:
it's _not_ less expensive in the git world.
In the git world, 1 and 2 aren't even separate things. They go together.
And you just sign it. End of story. It's so cheap to sign that it's not
even funny.
More importantly, signing 3 is meaningless. 3 only makes sense with a
known starting point. You should never sign a patch without also saying
what you're patching.
And once you do that, 1+2 and 1+3 are _exactly_ the same thing.
And since git always works on the 1+2 level, it would be inexcusably
stupid to sign anything but that. 3 doesn't even exist per se, although
it's obviously fully defined by 1+2.
So I don't see your point. You complain about git signing, but you
complain on grounds that do not _exist_ in git, and then your alternative
(1+3) which is senseless in a git world doesn't actually end up being
anything really different - just more expensive.
Linus
^ permalink raw reply
* Re: More problems...
From: Linus Torvalds @ 2005-04-29 17:51 UTC (permalink / raw)
To: Russell King; +Cc: git
In-Reply-To: <20050429171205.B30010@flint.arm.linux.org.uk>
On Fri, 29 Apr 2005, Russell King wrote:
>
> Not particularly nice, but very necessary, and apparantly the only
> way to get this to work. Grumble. Why am I seemingly the only one
> running into all these blocking problems.
Well, I suspect not a lot of people are actually using cogito for kernel
stuff.
I still use my old "git-pull-script" to update stuff. I know how it works,
and it does at least these things right (as long as "merge-base" works
right, of course - which so far it has for me since the re-write).
Linus
^ permalink raw reply
* Re: Odd decision of git-pasky-0.7 to do a merge
From: Linus Torvalds @ 2005-04-29 17:44 UTC (permalink / raw)
To: Russell King; +Cc: git
In-Reply-To: <20050429083615.A32271@flint.arm.linux.org.uk>
On Fri, 29 Apr 2005, Russell King wrote:
>
> Why it decided that a merge was necessary is beyond me. Any ideas?
> Did Linus forget to merge his tree properly?
It looks like it was unable to find the right common ancestor.
If you only had my stuff in it, the common ancestor _should_ have been the
parent (c60c390620e0abb60d4ae8c43583714bda27763f), which _should_ have
been your old top.
But maybe merge-base didn't work right?
Linus
^ permalink raw reply
* Re: Mercurial 0.4b vs git patchbomb benchmark
From: Tom Lord @ 2005-04-29 17:34 UTC (permalink / raw)
To: torvalds; +Cc: mpm, seanlkml, linux-kernel, git
In-Reply-To: <Pine.LNX.4.58.0504290854270.18901@ppc970.osdl.org>
From: Linus Torvalds <torvalds@osdl.org>
On Fri, 29 Apr 2005, Tom Lord wrote:
>
> On the other hand, you're asking people to sign whole trees and not
> just at first-import time but also for every change.
I don't agree.
Let's be more precise, then.
Sure, the commit determins the whole tree end result, but if you want to
sign the _tree_, you can do so: just tag the actual _tree_ object as "this
tree has been verified to be bug-free and non-baby-seal-clubbing".
But that's not what people do with tags. They sign a _commit_ object. And
yes, the commit object points to the tree, but it also points to the whole
history of other commit objects (and thus all historical trees etc), and
together with just common sense it is very obvious that what you're really
signing is that "point in time".
If you want to clarify it, you can always just say so in the tag. Instead
of saying "I tag this as something I have verified every byte of", you can
say "this was what I released as xxx", or "this commit contains my change"
or something.
A programmer publishing a change to the kernel has three pieces of
data in play. They are:
nn
1) the ancestry of their modified tree
2) the complete contents of their modified tree
3) input data for a patching program (let's call it "PATCH")
which, at the very least, satisfies the equation:
MOD_TREE = PATCH (this_diff, ORIG_TREE)
An upstream consumer, most often, is (should be) using (1) and (3).
In your system, the upstream consumer is given (1) and (2) and must
compute (3) for themselves. The upstream consumer can also be provided
a signed version of (3) but if clients are mostly relying on the (2)
then there are multiple vulnerabilities there.
The set of pairs of type (1) and (2) is a dual space to the set of
pairs of type (1) and (3). In that sense, it makes no mathematical
difference whether the programmer signs a {(1),(3)} pair or a {(1),(2)}
pair since either way, the other pair can be trivially derived.
On the other hand, signing documents which represent a {(1),(3)} pair
with robust accuracy is, in most cases, much much less expensive than
signing {(1),(2)} pairs with robust accuracy. This is a bit like the
difference between "*I* didn't set loose any mice in the house" vs. "I
have searched every corner of the house and swear there are no mice
here."
Another way to say that is that if someone gives me a signed {(1),(3)} pair
I am likely to be much more confident that the signature represents
an in-depth endorsement of the content as opposed to "here is what the
tools on my system happened to generate -- I hope it's what I meant".
> If I've changed five files, I should be signing a statement of:
>
> 1) my belief about the identity of the immediate ancestor tree
> 2) a robust summary of my changes, sufficient to recreate my
> new tree given a faithful copy of the ancestor
So _do_ exactly that. You can say that in the tag you're signing.
Which is pretty much exactly what Arch does except that, in the case
of Arch, the signed diff is actually used directly to produce the mod
tree. There isn't a step in the process where a programmer reads
a purported diff, assumes that the signed tree accurately reflects
that diff, and then merges against the signed tree rather than the
diff.
The Arch approach also has the win that the signed diffs are useful
even in the absense of the ORIG_TREE. In the Arch world, we use this
for the form of selective merging that we call "cherry-picking" (picking
the desired changes from somebody else's line of development while
skipping those which are not desired -- yet still being able to proceed
with bidirectional merging in a simple way).
The Arch approach also has the win that it amounts to delta-compression,
simplifying the design of efficient transports and helping to tame
I/O bandwidth costs in the local case. A lot of good features simply
"fall out" of this approach.
This is kind of a yin-yang thing. It's also valuable, in my view, to
sign {(1),(2)} pairs. It's also (in a more obscure way) valuable to
sign {(1),(2),(3)} triples, especially if clients are regularly validating
them by making sure the triple describes a true diff application.
So one ultimately wants both functionalities, really.
Signing trees which are really defined by a diff is a handy checksum
on the accuracy of tools which people are using but it isn't a substitute
for signing the diff itself and using it as the primary definition of
the tree it generates when combined with the immediate ancestor(s).
Signing trees is also handy when that signature is then further linked
to a set of binaries.
Signing trees also is easier to implement and so gets git off the ground
faster.
But there's more to do, if a serious system is desired.
-t
^ permalink raw reply
* Re: [PATCH]: first take at cleanup of #include, xmalloc / xrealloc, git status report usage.
From: Klaus Robert Suetterlin @ 2005-04-29 17:07 UTC (permalink / raw)
To: Edgar Toernig; +Cc: git
In-Reply-To: <20050429182407.5f6afd15.froese@gmx.de>
Thanks for reviewing this lengthy patch!
On Fri, Apr 29, 2005 at 06:24:07PM +0200, Edgar Toernig wrote:
> Robert S?tterlin wrote:
> >[...]
> > +static int
> > +create_directories(const char *path)
> > {
> > - int len = strlen(path);
> > - char *buf = xmalloc(len + 1);
> > - const char *slash = path;
> > + char *buf = (char *)path;
> > + char *slash = buf;
> >
> > while ((slash = strchr(slash+1, '/')) != NULL) {
> > - len = slash - path;
> > - memcpy(buf, path, len);
> > - buf[len] = 0;
> > - mkdir(buf, 0755);
> > + *slash = '\0';
> > + if (0 != mkdir(buf, 0755))
> > + return error("Unable to mkdir(``%s'', 0755)", buf);
> > + *slash = '/';
>
> You need the temp buffer. Simply casting the const away may
> shut up the compiler but it's not correct.
Ok, I see! Someone will pass a const char * (e.g. static string,
readonly mmap, ...). In that case I would rather change the signature
of the function ;). My am I a smart ass, ain't I.
What I wanted to achieve was getting rid of xmalloc that would just
die("horribly") in case we cannot allocate the memory. Or some
other hacked up malloc / realloc alternative.
Aside: I really do not like the current habit of die("if anything does
not work out.") in git code all that much. People seem to take
the die() as cast in stone, and do not free resources in code
pathes that lead to a die(), currently. Of course this die()
might change in the near future. And we will have to examine
every die() very carefully to make sure Joe Lazy Programmer
didn't leave any garbage lying around.
IMHO, the right thing for die() would be to dump core instead of just
exiting. As die() should be called in the ``can't happen'' or rather
``isn't resolved correctly'' cases only. And programmers would be
able to use the core to identify these cases quickly.
Unfortunately what You say is true and I cannot see a way around
some kind of working copy (except for forcing the caller to provide
a non-const char*). Maybe I will put ``char scratchpath[MAXPATH + 1];''
and ``#include <sys/param.h>'' in cache.h :).
>
> > - if (errno != EEXIST)
> > + if (EEXIST != errno)
>
> Too much Star Wars? Joda-speak?
No. This is my prefered style for two reasons:
1) Putting the non-l-value on the left hand side protects against
my most common typo: "=" instead of "==" or "!=". No matter which
compiler or warning level.
2) More often than not the variable part will be longer than
``errno''. So putting EEXIST and the comparator front helps seeing
the condition I test against. Just compare:
while (-1 != (ch = getopt(argc, argv, "abcde:fg:h:ijkl:mnopq:r:stuvwx:y:z")))
while ((ch = getopt(argc, argv, "abcde:fg:h:ijkl:mnopq:r:stuvwx:y:z")) != -1)
>
> Ciao, ET.
>
>
> PS: the mkdir mode should be 0777 ...
Thanks! I did just a literal copy of what was there before. I
added the check for the return value, to get the right diagnostic
output.
Kind regards,
--Robert Suetterlin (robert@mpe.mpg.de)
phone: (+49)89 / 30000-3546 fax: (+49)89 / 30000-3950
^ permalink raw reply
* Re: Mercurial 0.4b vs git patchbomb benchmark
From: Linus Torvalds @ 2005-04-29 17:09 UTC (permalink / raw)
To: Matt Mackall; +Cc: Sean, linux-kernel, git
In-Reply-To: <20050429163705.GU21897@waste.org>
On Fri, 29 Apr 2005, Matt Mackall wrote:
>
> That's because no one paid attention until I posted performance
> numbers comparing it to git! Mercurial's goals are:
>
> - to scale to the kernel development process
> - to do clone/pull style development
> - to be efficient in CPU, memory, bandwidth, and disk space
> for all the common SCM operations
> - to have strong repo integrity
Ok, sounds good. Have you looked at how it scales over time, ie what
happens with files that have a lot of delta's?
Let's see how these things work out..
Linus
^ permalink raw reply
* Re: Mercurial 0.4b vs git patchbomb benchmark
From: Matt Mackall @ 2005-04-29 16:52 UTC (permalink / raw)
To: Morten Welinder; +Cc: Linus Torvalds, Sean, linux-kernel, git
In-Reply-To: <118833cc05042908181d09bdfd@mail.gmail.com>
On Fri, Apr 29, 2005 at 11:18:20AM -0400, Morten Welinder wrote:
> > I had three design goals. "disk space" wasn't one of them
>
> And, if at some point it should become an issue, it's fixable. Since
> access to objects is fairly centralized and since they are
> immutable, it would be quite simple to move an arbitrary selection
> of the objects into some other storage form which could take
> similarities between objects into account.
This is not a fix, this is a band-aid. A fix is fitting all the data
in 10 times less space without sacrificing too much performance.
> So disk space and its cousin number-of-files are both when-and-if
> problems. And not scary ones at that.
But its sibling bandwidth _is_ a problem. The delta between 2.6.10 and
2.6.11 in git terms will be much larger than a _full kernel tarball_.
Simply checking in patch-2.6.11 on top of 2.6.10 as a single changeset
takes 41M. Break that into a thousand overlapping deltas (ie the way
it is actually done) and it will be much larger.
--
Mathematics is the supreme nostalgia of our time.
^ permalink raw reply
* Re: Mercurial 0.4b vs git patchbomb benchmark
From: Bill Davidsen @ 2005-04-29 16:46 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Matt Mackall, Sean, linux-kernel, git
In-Reply-To: <Pine.LNX.4.58.0504290728090.18901@ppc970.osdl.org>
Linus Torvalds wrote:
>
> On Fri, 29 Apr 2005, Matt Mackall wrote:
>
>>Mercurial is even younger (Linus had a few days' head start, not to
>>mention a bunch of help), and it is already as fast as git, relatively
>>easy to use, much simpler, and much more space and bandwidth
>>efficient.
>
>
> You've not mentioned two out of my three design goals:
> - distribution
> - reliability/trustability
>
> ie does mercurial do distributed merges, which git was designed for, and
> does mercurial notice single-bit errors in a reasonably secure manner, or
> can people just mess with history willy-nilly?
>
> For the latter, the cryptographic nature of sha1 is an added bonus - the
> _big_ issue is that it is a good hash, and an _exteremely_ effective CRC
> of the data. You can't mess up an archive and lie about it later. And if
> you have random memory or filesystem corruption, it's not a "shit happens"
> kind of situation - it's a "uhhoh, we can catch it (and hopefully even fix
> it, thanks to distribution)" thing.
>
> I had three design goals. "disk space" wasn't one of them, so you've
> concentrated on only one so far in your arguments.
Reliability is a must have, but disk space matters in the real world if
all other things are roughly equal. And bandwidth requirements are
certainly another real issue if they result in significant delay.
Isn't the important thing having the SCC reliable and easy to use, as
in supports the things you want to do without jumping through hoops? One
advantage of Mercurial is that it can be the only major project for
someone who seems to understand the problems, as opposed to taking the
time of someone (you) who has a load of other things in the fire. And if
there isn't time to do all the things you want, perhaps generating a
wisj list and stepping back would be a good thing.
If you have the energy and time to stay with git, I'm sure it will be
great, but you might want to provide input on Mercurial and let it run.
PS: I don't think the performance difference is enough to constitute a
real advantage in either direction.
--
-bill davidsen (davidsen@tmr.com)
"The secret to procrastination is to put things off until the
last possible moment - but no longer" -me
^ permalink raw reply
* Re: Mercurial 0.4b vs git patchbomb benchmark
From: Matt Mackall @ 2005-04-29 16:37 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Sean, linux-kernel, git
In-Reply-To: <Pine.LNX.4.58.0504290728090.18901@ppc970.osdl.org>
On Fri, Apr 29, 2005 at 07:34:15AM -0700, Linus Torvalds wrote:
>
>
> On Fri, 29 Apr 2005, Matt Mackall wrote:
> >
> > Mercurial is even younger (Linus had a few days' head start, not to
> > mention a bunch of help), and it is already as fast as git, relatively
> > easy to use, much simpler, and much more space and bandwidth
> > efficient.
>
> You've not mentioned two out of my three design goals:
> - distribution
> - reliability/trustability
>
> ie does mercurial do distributed merges, which git was designed for, and
> does mercurial notice single-bit errors in a reasonably secure manner, or
> can people just mess with history willy-nilly?
Distribution: yes, it does BK/Monotone-style branching and merging.
In fact, these should be more "correct" than git as it has DAG
information at the file level in the case where there are multiple
ancestors at the changeset graph level:
M M1 M2
AB
|`-------v M2 clones M
aB AB file A is change in mainline
|`---v AB' file B is changed in M2
| aB / | M1 clones M
| ab/ | M1 changes B
| ab' | M1 merges from M2, changes to B conflict
| | A'B' M2 changes A
`---+--.|
| a'B' M2 merges from mainline, changes to A conflict
`--.|
??? depending on which ancestor we choose, we will have
to redo A hand-merge, B hand-merge, or both
but if we look at the files independently, everything
is fine
> For the latter, the cryptographic nature of sha1 is an added bonus - the
> _big_ issue is that it is a good hash, and an _exteremely_ effective CRC
> of the data. You can't mess up an archive and lie about it later. And if
> you have random memory or filesystem corruption, it's not a "shit happens"
> kind of situation - it's a "uhhoh, we can catch it (and hopefully even fix
> it, thanks to distribution)" thing.
Reliability/trustability: Mercurial is using a SHA1 hash as a checksum
as well, much like Monotone and git. A changeset contains a hash of a
manifest which contains a hash of each file in the project, so you can
do things like sign the manifest hash (though I haven't implemented it
yet. Making a backup is as simple as making a hardlink branch:
mkdir backup
cd backup
hg branch ../linux # takes about a second
> I had three design goals. "disk space" wasn't one of them, so you've
> concentrated on only one so far in your arguments.
That's because no one paid attention until I posted performance
numbers comparing it to git! Mercurial's goals are:
- to scale to the kernel development process
- to do clone/pull style development
- to be efficient in CPU, memory, bandwidth, and disk space
for all the common SCM operations
- to have strong repo integrity
It's been doing all that quite nicely since its first release.
The UI is also pretty straightforward:
Setting up a Mercurial project:
$ cd linux/
$ hg init # creates .hg
$ hg status # show changes between repo and working dir
$ hg addremove # add all unknown files and remove all missing files
$ hg commit # commit all changes, edit changelog entry
Mercurial will look for a file named .hgignore in the root of your
repository contains a set of regular expressions to ignore in file
paths.
Mercurial commands:
$ hg history # show changesets
$ hg log Makefile # show commits per file
$ hg diff # generate a unidiff
$ hg checkout # check out the tip revision
$ hg checkout <hash> # check out a specified changeset
$ hg add foo # add a new file for the next commit
$ hg remove bar # mark a file as removed
Branching and merging:
$ cd ..
$ mkdir linux-work
$ cd linux-work
$ hg branch ../linux # create a new branch
$ hg checkout # populate the working directory
$ <make changes>
$ hg commit
$ cd ../linux
$ hg merge ../linux-work # pull changesets from linux-work
Importing patches:
Fast:
$ patch < ../p/foo.patch
$ hg addremove
$ hg commit
Faster:
$ patch < ../p/foo.patch
$ hg commit `lsdiff -p1 ../p/foo.patch`
Fastest:
$ cat ../p/patchlist | xargs hg import -p1 -b ../p
Network support:
# export your .hg directory as a directory on your webserver
foo$ ln -s .hg ~/public_html/hg-linux
# merge changes from a remote machine
bar$ hg init # create an empty repo
bar$ hg merge http://foo/~user/hg-linux # populate it
bar$ <do some work>
bar$ hg merge http://foo/~user/hg-linux # resync
This is just a proof of concept of grabbing byte ranges, and is not
expected to perform well.
--
Mathematics is the supreme nostalgia of our time.
^ permalink raw reply
* Re: [PATCH]: first take at cleanup of #include, xmalloc / xrealloc, git status report usage.
From: Edgar Toernig @ 2005-04-29 16:24 UTC (permalink / raw)
To: Robert Sütterlin; +Cc: git
In-Reply-To: <bfbb1f23220e1918afe70d4cf3de24f5@mpe.mpg.de>
Robert Sütterlin wrote:
>[...]
> +static int
> +create_directories(const char *path)
> {
> - int len = strlen(path);
> - char *buf = xmalloc(len + 1);
> - const char *slash = path;
> + char *buf = (char *)path;
> + char *slash = buf;
>
> while ((slash = strchr(slash+1, '/')) != NULL) {
> - len = slash - path;
> - memcpy(buf, path, len);
> - buf[len] = 0;
> - mkdir(buf, 0755);
> + *slash = '\0';
> + if (0 != mkdir(buf, 0755))
> + return error("Unable to mkdir(``%s'', 0755)", buf);
> + *slash = '/';
You need the temp buffer. Simply casting the const away may
shut up the compiler but it's not correct.
> - if (errno != EEXIST)
> + if (EEXIST != errno)
Too much Star Wars? Joda-speak?
Ciao, ET.
PS: the mkdir mode should be 0777 ...
^ permalink raw reply
* Re: More problems...
From: Russell King @ 2005-04-29 16:12 UTC (permalink / raw)
To: git
In-Reply-To: <20050429170127.A30010@flint.arm.linux.org.uk>
On Fri, Apr 29, 2005 at 05:01:27PM +0100, Russell King wrote:
> Ok. cogito-0.8.
>
> rmk@dyn-67:[linux-2.6-rmk]:<1049> cg-update origin
> `../linux-2.6/.git/refs/heads/master' -> `.git/refs/heads/origin'
> `../linux-2.6/.git/objects/00/78aeb85737197a84af1eeb0353dbef74427901' -> `.git/objects/00/78aeb85737197a84af1eeb0353dbef74427901'
> cp: cannot create link `.git/objects/00/78aeb85737197a84af1eeb0353dbef74427901': File exists
> `../linux-2.6/.git/objects/01/ca31cc7bfdd18d6f72288915021730442f386d' -> `.git/objects/01/ca31cc7bfdd18d6f72288915021730442f386d'
> cp: cannot create link `.git/objects/01/ca31cc7bfdd18d6f72288915021730442f386d': File exists
> `../linux-2.6/.git/objects/04/17820d15efac837a84f9ade46f56339016a282' -> `.git/objects/04/17820d15efac837a84f9ade46f56339016a282'
> cp: cannot create link `.git/objects/04/17820d15efac837a84f9ade46f56339016a282': File exists
> `../linux-2.6/.git/objects/07/da010b67d4d715b5e97dfb824eb70433776a20' -> `.git/objects/07/da010b67d4d715b5e97dfb824eb70433776a20'
> cp: cannot create link `.git/objects/07/da010b67d4d715b5e97dfb824eb70433776a20': File exists
> `../linux-2.6/.git/objects/07/5d3961a119e8f27294cd77193f8fee7908a521' -> `.git/objects/07/5d3961a119e8f27294cd77193f8fee7908a521'
> ...
> cp: cannot create link `.git/objects/fc/1428905472a61e8e51057a4237acab5d8594d8': File exists
> `../linux-2.6/.git/objects/fc/373c483e62dc1bbc5c3915f2d3c795fb316ec5' -> `.git/objects/fc/373c483e62dc1bbc5c3915f2d3c795fb316ec5'
> cp: cannot create link `.git/objects/fc/373c483e62dc1bbc5c3915f2d3c795fb316ec5': File exists
> `../linux-2.6/.git/objects/ff/c3be3dff7e20e2ad5367fa8d6d0d2f0baa8a24' -> `.git/objects/ff/c3be3dff7e20e2ad5367fa8d6d0d2f0baa8a24'
> cp: cannot create link `.git/objects/ff/c3be3dff7e20e2ad5367fa8d6d0d2f0baa8a24': File exists
> `../linux-2.6/.git/objects/ff/8b49966a9f6ed23f6489bb986de87a14d4b783' -> `.git/objects/ff/8b49966a9f6ed23f6489bb986de87a14d4b783'
> cp: cannot create link `.git/objects/ff/8b49966a9f6ed23f6489bb986de87a14d4b783': File exists
> cg-pull: rsync error
>
> rmk@dyn-67:[linux-2.6-rmk]:<1052> md5sum .git/objects/ff/8b49966a9f6ed23f6489bb986de87a14d4b783 ../linux-2.6/.git/objects/ff/8b49966a9f6ed23f6489bb986de87a14d4b783
> 194b70d0eed786807e14e97dd0a5ad8d .git/objects/ff/8b49966a9f6ed23f6489bb986de87a14d4b783
> 194b70d0eed786807e14e97dd0a5ad8d ../linux-2.6/.git/objects/ff/8b49966a9f6ed23f6489bb986de87a14d4b783
> rmk@dyn-67:[linux-2.6-rmk]:<1053> vdir .git/objects/ff/8b49966a9f6ed23f6489bb986de87a14d4b783 ../linux-2.6/.git/objects/ff/8b49966a9f6ed23f6489bb986de87a14d4b783
> -rw-rw-r-- 1 rmk rmk 3070 Apr 28 10:43 .git/objects/ff/8b49966a9f6ed23f6489bb986de87a14d4b783
> -rw-r--r-- 1 rmk rmk 3070 Apr 29 16:50 ../linux-2.6/.git/objects/ff/8b49966a9f6ed23f6489bb986de87a14d4b783
>
> What seems to be happening is that I create changes in my tree, rsync
> them out to kernel.org. Linus pulls them into his tree. I pull them
> back into my reference tree, and then try and update my working tree.
>
> By that time, the object files in the reference tree appear to have
> a newer timestamp than the corresponding ones in my local tree, and
> cp -lua fails.
>
> Which means cogito fails to work for me... Help.
I've worked around it by doing:
$ rm -rf .git/objects/*
$ cg-update origin
Not particularly nice, but very necessary, and apparantly the only
way to get this to work. Grumble. Why am I seemingly the only one
running into all these blocking problems.
--
Russell King
^ permalink raw reply
* More problems...
From: Russell King @ 2005-04-29 16:01 UTC (permalink / raw)
To: git
Ok. cogito-0.8.
rmk@dyn-67:[linux-2.6-rmk]:<1049> cg-update origin
`../linux-2.6/.git/refs/heads/master' -> `.git/refs/heads/origin'
`../linux-2.6/.git/objects/00/78aeb85737197a84af1eeb0353dbef74427901' -> `.git/objects/00/78aeb85737197a84af1eeb0353dbef74427901'
cp: cannot create link `.git/objects/00/78aeb85737197a84af1eeb0353dbef74427901': File exists
`../linux-2.6/.git/objects/01/ca31cc7bfdd18d6f72288915021730442f386d' -> `.git/objects/01/ca31cc7bfdd18d6f72288915021730442f386d'
cp: cannot create link `.git/objects/01/ca31cc7bfdd18d6f72288915021730442f386d': File exists
`../linux-2.6/.git/objects/04/17820d15efac837a84f9ade46f56339016a282' -> `.git/objects/04/17820d15efac837a84f9ade46f56339016a282'
cp: cannot create link `.git/objects/04/17820d15efac837a84f9ade46f56339016a282': File exists
`../linux-2.6/.git/objects/07/da010b67d4d715b5e97dfb824eb70433776a20' -> `.git/objects/07/da010b67d4d715b5e97dfb824eb70433776a20'
cp: cannot create link `.git/objects/07/da010b67d4d715b5e97dfb824eb70433776a20': File exists
`../linux-2.6/.git/objects/07/5d3961a119e8f27294cd77193f8fee7908a521' -> `.git/objects/07/5d3961a119e8f27294cd77193f8fee7908a521'
...
cp: cannot create link `.git/objects/fc/1428905472a61e8e51057a4237acab5d8594d8': File exists
`../linux-2.6/.git/objects/fc/373c483e62dc1bbc5c3915f2d3c795fb316ec5' -> `.git/objects/fc/373c483e62dc1bbc5c3915f2d3c795fb316ec5'
cp: cannot create link `.git/objects/fc/373c483e62dc1bbc5c3915f2d3c795fb316ec5': File exists
`../linux-2.6/.git/objects/ff/c3be3dff7e20e2ad5367fa8d6d0d2f0baa8a24' -> `.git/objects/ff/c3be3dff7e20e2ad5367fa8d6d0d2f0baa8a24'
cp: cannot create link `.git/objects/ff/c3be3dff7e20e2ad5367fa8d6d0d2f0baa8a24': File exists
`../linux-2.6/.git/objects/ff/8b49966a9f6ed23f6489bb986de87a14d4b783' -> `.git/objects/ff/8b49966a9f6ed23f6489bb986de87a14d4b783'
cp: cannot create link `.git/objects/ff/8b49966a9f6ed23f6489bb986de87a14d4b783': File exists
cg-pull: rsync error
rmk@dyn-67:[linux-2.6-rmk]:<1052> md5sum .git/objects/ff/8b49966a9f6ed23f6489bb986de87a14d4b783 ../linux-2.6/.git/objects/ff/8b49966a9f6ed23f6489bb986de87a14d4b783
194b70d0eed786807e14e97dd0a5ad8d .git/objects/ff/8b49966a9f6ed23f6489bb986de87a14d4b783
194b70d0eed786807e14e97dd0a5ad8d ../linux-2.6/.git/objects/ff/8b49966a9f6ed23f6489bb986de87a14d4b783
rmk@dyn-67:[linux-2.6-rmk]:<1053> vdir .git/objects/ff/8b49966a9f6ed23f6489bb986de87a14d4b783 ../linux-2.6/.git/objects/ff/8b49966a9f6ed23f6489bb986de87a14d4b783
-rw-rw-r-- 1 rmk rmk 3070 Apr 28 10:43 .git/objects/ff/8b49966a9f6ed23f6489bb986de87a14d4b783
-rw-r--r-- 1 rmk rmk 3070 Apr 29 16:50 ../linux-2.6/.git/objects/ff/8b49966a9f6ed23f6489bb986de87a14d4b783
What seems to be happening is that I create changes in my tree, rsync
them out to kernel.org. Linus pulls them into his tree. I pull them
back into my reference tree, and then try and update my working tree.
By that time, the object files in the reference tree appear to have
a newer timestamp than the corresponding ones in my local tree, and
cp -lua fails.
Which means cogito fails to work for me... Help.
--
Russell King
^ permalink raw reply
* [PATCh] jit-trackdown
From: David Greaves @ 2005-04-29 16:03 UTC (permalink / raw)
To: Junio C Hamano; +Cc: GIT Mailing Lists
Hi Junio
Excellent tool :)
Should really be cg-trackdown
David
This patch allows the use of symbolic commits from Cogito's
.git/refs/heads and tags structure eg:
jit-trackdown HEAD etc/db/schema.sql
or
jit-trackdown v3.2 etc/db/schema.sql
Signed-off-by: David Greaves <david@dgreaves.com>
---
--- jit-trackdown.orig 2005-04-29 16:57:40.278707704 +0100
+++ jit-trackdown 2005-04-29 16:47:16.495483693 +0100
@@ -1,6 +1,8 @@
#!/bin/sh
# Usage: jit-trackdown <commit> paths...
+# <commit> can be the symbolic name HEAD
+# or a tag or head identifier.
tmp=.jit-trackdown.$$
hits=$tmp-hits
@@ -10,6 +12,14 @@
tty -s || to_tty=:
head="$1"
+if [ $head == "HEAD" ]; then
+ head=$(cat .git/HEAD)
+elif [ -f .git/refs/tags/$head ]; then
+ head=$(cat .git/refs/tags/$head)
+elif [ -f .git/refs/heads/$head ]; then
+ head=$(cat .git/refs/heads/$head)
+fi
+
shift
rev-list "$head" |
while read commit
^ permalink raw reply
* Re: Mercurial 0.4b vs git patchbomb benchmark
From: Linus Torvalds @ 2005-04-29 15:58 UTC (permalink / raw)
To: Tom Lord; +Cc: mpm, seanlkml, linux-kernel, git
In-Reply-To: <200504291544.IAA23584@emf.net>
On Fri, 29 Apr 2005, Tom Lord wrote:
>
> On the other hand, you're asking people to sign whole trees and not just at
> first-import time but also for every change.
I don't agree.
Sure, the commit determins the whole tree end result, but if you want to
sign the _tree_, you can do so: just tag the actual _tree_ object as "this
tree has been verified to be bug-free and non-baby-seal-clubbing".
But that's not what people do with tags. They sign a _commit_ object. And
yes, the commit object points to the tree, but it also points to the whole
history of other commit objects (and thus all historical trees etc), and
together with just common sense it is very obvious that what you're really
signing is that "point in time".
If you want to clarify it, you can always just say so in the tag. Instead
of saying "I tag this as something I have verified every byte of", you can
say "this was what I released as xxx", or "this commit contains my change"
or something.
> If I've changed five files, I should be signing a statement of:
>
> 1) my belief about the identity of the immediate ancestor tree
> 2) a robust summary of my changes, sufficient to recreate my
> new tree given a faithful copy of the ancestor
So _do_ exactly that. You can say that in the tag you're signing.
Linus
^ permalink raw reply
* [PATCH] Add cg-tag-ls command
From: Steve Hoelzer @ 2005-04-29 15:55 UTC (permalink / raw)
To: git
cg-tag-ls lists all tags in a GIT repository.
Signed-off-by: Steve Hoelzer <shoelzer@gmail.com>
Index: Makefile
===================================================================
--- c3aa1e6b53cc59d5fbe261f3f859584904ae3a63/Makefile (mode:100644
sha1:d73bea1cbb9451a89b03d6066bf2ed7fec32fd31)
+++ uncommitted/Makefile (mode:100644)
@@ -44,7 +44,7 @@
cg-add cg-admin-lsobj cg-cancel cg-clone cg-commit cg-diff \
cg-export cg-help cg-init cg-log cg-ls cg-merge cg-mkpatch \
cg-patch cg-pull cg-branch-add cg-branch-ls cg-rm cg-seek cg-status \
- cg-tag cg-update cg-Xlib
+ cg-tag cg-tag-ls cg-update cg-Xlib
COMMON= read-cache.o
Index: cg-help
===================================================================
--- c3aa1e6b53cc59d5fbe261f3f859584904ae3a63/cg-help (mode:100755
sha1:d16446c005c4698f408bf651afd718d95f5a9cfe)
+++ uncommitted/cg-help (mode:100755
sha1:31ea484f757fc4bf5de25acb621e219f4bfb0f52)
@@ -42,6 +42,7 @@
cg-seek [COMMIT_ID]
cg-status
cg-tag TNAME [COMMIT_ID]
+ cg-tag-ls
cg-update [BNAME]
cg-version
Index: cg-tag-ls
===================================================================
--- /dev/null (tree:c3aa1e6b53cc59d5fbe261f3f859584904ae3a63)
+++ uncommitted/cg-tag-ls (mode:100755
sha1:15b5db0cd2a023a078f467d1bcd3bc0c5eb833dc)
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+#
+# List stored GIT tags.
+# Copyright (c) Steve Hoelzer 2005
+#
+# Takes no parameters.
+
+. cg-Xlib
+
+mkdir -p .git/refs/tags
+[ "$(find .git/refs/tags -follow -type f)" ] \
+ || die "List of tags is empty. See cg-tag."
+
+cd .git/refs/tags
+for tag in *; do
+ echo -n $tag
+ echo -ne "\t"
+ cat $tag
+done
^ permalink raw reply
* Re: About gitweb.cgi bug
From: Kay Sievers @ 2005-04-29 15:53 UTC (permalink / raw)
To: Tomasz bla Fortuna; +Cc: git
In-Reply-To: <e72f90b8050429062342724335@mail.gmail.com>
On Fri, 2005-04-29 at 15:23 +0200, Tomasz bla Fortuna wrote:
> Hi,
> I've found html injection bug:
> http://www.kernel.org/git/gitweb.cgi?p=%3Cimg%20src=%22http://af.gliwice.pl/p.png%22%3Ecogito%2Fcogito.git;a=log
> May lead to redirection to some pr0n sites using kernel.org address...
> but its nothing.
I've sent a fix for this to the kernel.org master.
Thanks,
Kay
^ permalink raw reply
* Re: Mercurial 0.4b vs git patchbomb benchmark
From: Tom Lord @ 2005-04-29 15:44 UTC (permalink / raw)
To: torvalds; +Cc: mpm, seanlkml, linux-kernel, git
In-Reply-To: <Pine.LNX.4.58.0504290728090.18901@ppc970.osdl.org>
> ie does mercurial do distributed merges, which git was designed for, and
> does mercurial notice single-bit errors in a reasonably secure manner, or
> can people just mess with history willy-nilly?
> For the latter, the cryptographic nature of sha1 is an added bonus - the
> _big_ issue is that it is a good hash, and an _exteremely_ effective CRC
> of the data. You can't mess up an archive and lie about it later.
On the other hand, you're asking people to sign whole trees and not just at
first-import time but also for every change.
That's an impedence mismatch and undermines the security features of the
approach you're taking and here is why:
I shouldn't sign anything I haven't reviewed pretty carefully. For
the kernel and in many other situations, it is too expensive to review
the whole tree. Thus, the thing actually signed and the thing meant
by the signature are not equal. I sign a tree, in this system,
because I think the right diffs and only the right diffs have been
applied to it. My signature is intended to mean, though, that I vouche
for the *diffs*, not the tree.
If I've changed five files, I should be signing a statement of:
1) my belief about the identity of the immediate ancestor tree
2) a robust summary of my changes, sufficient to recreate my
new tree given a faithful copy of the ancestor
That's a short enough amount of data that a human can really review it
and thus it makes the signatures much more meaningful.
Probably doesn't matter much other than in cases where a mainline
is undergoing massive batch-patching based mostly on a web of trust.
But in that case --- someone or something generates purported diffs of
a tree; someone or something else scans those diffs and decides they
look good ---- and then on this basis, something distinct from
directly using those diffs occurs. The diffs were used to vette the
change; the signature asserts that a certain tree is a faithful result
of applying those diffs. Nothing checks that second assertion -- it's
taken on faith.
-t
^ permalink raw reply
* Val Henson's critique of hash-based content storage systems
From: Rob Jellinghaus @ 2005-04-29 0:06 UTC (permalink / raw)
To: git
I assume most people here have read this, but just in case:
http://www.usenix.org/events/hotos03/tech/full_papers/henson/henson.pdf
Is git vulnerable to attacks in the event that SHA-1 is broken?
If an attacker used an SHA-1 attack to create a blob that matched the hash of
some well-known git object (say, the tree for Linux 2.7-rc1), and spammed public
git repositories with it ahead of Linus's release, what would be the potential
for mischief, and what would the recovery process be?
It seems that git is optimized to support networks of trust, so provided you
accept only signed commits from people you trust, it's likely that corruption
and mischief can be mostly avoided. But probably not completely; there is still
a window of vulnerability.
It seems that git repositories could (at great expense) be regenerated to use a
new hash algorithm. Is that the plan if SHA-1 is compromised (or comes so close
to compromise as to make Linus nervous ;-)?
Cheers,
Rob
^ permalink raw reply
* Re: Mercurial 0.4b vs git patchbomb benchmark
From: Morten Welinder @ 2005-04-29 15:18 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Matt Mackall, Sean, linux-kernel, git
In-Reply-To: <Pine.LNX.4.58.0504290728090.18901@ppc970.osdl.org>
> I had three design goals. "disk space" wasn't one of them
And, if at some point it should become an issue, it's fixable. Since
access to objects
is fairly centralized and since they are immutable, it would be quite
simple to move
an arbitrary selection of the objects into some other storage form
which could take
similarities between objects into account.
If you chose the selection of objects with care -- say those for files
that have changed
many times since -- it shouldn't even hurt performance of day-to-day
tasks (which aren't
likely to ever need those objects).
So disk space and its cousin number-of-files are both when-and-if
problems. And not
scary ones at that.
Morten
^ 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