{"thread":{"id":"9312","subject":"Efficient way to import snapshots?","startedAt":"2007-07-30T18:07:11Z","lastAt":"2007-07-31T16:15:24Z","messageCount":27,"participants":["Craig Boston","Linus Torvalds","Junio C Hamano","Jakub Narebski","David Kastrup","Theodore Tso","Florian Weimer"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"49119","messageId":"20070730180710.GA64467@nowhere","threadId":"9312","inReplyTo":null,"subject":"Efficient way to import snapshots?","fromName":"Craig Boston","fromEmail":"craig@olyun.gank.org","sentAt":"2007-07-30T18:07:11Z","receivedAt":"2007-07-30T18:07:11Z","isPatch":false,"sender":{"key":"craig@olyun.gank.org","avatar":null},"body":"Hello, I'm seeking some input from git users/developers to try and solve\na problem I'm encountering.  I'm new with git, having used quite a bit\nof Subversion and SVK in the past, but have heard good things and\ndecided to give it a try.\n\nFirst, a little bit about what I'm trying to accomplish.  There is a\nlarge source tree -- FreeBSD to be specific -- which is maintained in\nCVS.  I want to have several local branches where I can develop specific\nprojects.  Each of these branches should derive from either the HEAD of\nthe CVS tree, or from one of the release branches (known as the -STABLE\nbranch for a particular version of the OS).\n\nThat said, I really don't want to have to import the entire CVS\nrepository.  It has many, many branches and tags that I'm not interested\nin, and I really don't need the entire history of the project.  I don't\neven really need individual commit history.  I can see that easily enough\non cvsweb.  Repo size is a big factor as I need to replicate it between\nseveral different work machines, some of which don't have unlimited disk\nspace.\n\nWhat I'm currently doing (using SVK) is nightly, taking a snapshot using\ncvsup of each of the 3 branches that I care about, then using \"svk\nimport\" to pull the snapshot into a local branch that I treat as a\nvendor branch.  My projects are branched off those and I regularly\nsmerge changes over.  It works pretty well for me, the only downside is\nthat svk isn't exactly fast, having to load lots of perl modules for\nevery command.\n\nI'd like to do something similar with git -- I like the idea of it\nhaving many less dependencies that must be installed, and it's supposed\nto be quite a bit faster when dealing with working copies.  From reading\nabout it I think it may also be easier to generate diffs of my branches\nfrom their origins.\n\nSo far the main snag I've found is that AFAIK there's no equivalent to\n\"svk import\" to load a big tree (~37000 files) into a branch and commit\nthe changes.  Here's the procedure I've come up with:\n\ncd /path/to/git/repo\ngit checkout vendor_branch_X\ngit rm -r .\ncp -R /path/to/cvs/checkout_X/* ./\ngit add .\ngit commit -m\"Import yyyymmdd snapshot\"\n\nHowever this has quite a few disadvantages when compared to svk.  The\nfirst is that I have to checkout into a working directory and then copy\nthe files from the cvs checkout.  It is also considerably slower than\nsvk import, about 7-8 times on average.  When there are a lot of\nchanges I've seen the git process use upwards of 1GB of memory; it\nactually died the first time I tried it because I didn't have any swap\nconfigured.\n\nNow, I don't have very much experience with git, so for my question: Is\nthere a better way to do this?  Either importing a lot of files into\ngit, or a better solution for that I'm trying to do.\n\nAny pointers would be much appreciated.\n\nThanks!\n\nCraig\n"},{"id":"49121","messageId":"alpine.LFD.0.999.0707301144180.4161@woody.linux-foundation.org","threadId":"9312","inReplyTo":"20070730180710.GA64467@nowhere","subject":"Re: Efficient way to import snapshots?","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-07-30T18:56:56Z","receivedAt":"2007-07-30T18:56:56Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Mon, 30 Jul 2007, Craig Boston wrote:\n> \n> So far the main snag I've found is that AFAIK there's no equivalent to\n> \"svk import\" to load a big tree (~37000 files) into a branch and commit\n> the changes.  Here's the procedure I've come up with:\n> \n> cd /path/to/git/repo\n> git checkout vendor_branch_X\n> git rm -r .\n> cp -R /path/to/cvs/checkout_X/* ./\n> git add .\n> git commit -m\"Import yyyymmdd snapshot\"\n\nOuch.\n\nWhat you want to do should fit git very well, but doing it that way is \nquite expensive.\n\nMight I suggest just doing the .git thing *directly* in the CVS checkout \ninstead?\n\nIt should literally be as easy as doing something like\n\n\tcd /path/to/cvs/checkout_X\n\texport GIT_DIR=/path/to/git/repo\n\tgit add .\n\tgit commit -m\"Import yyyymmdd snapshot\"\n\nand you never copy anything around, and git will just notice on its own \nwhat CVS has changed.\n\nYou'd have to make sure that you have the CVS directories ignored, of \ncourse, and if you don't want to change the CVS directory at all (which is \na good idea!) you'd need to do that by using the \"ignore\" file in your \nGIT_DIR, and just having the CVS entry there, instead of adding a\n\".gitignore\" file to the working tree and checking it in.\n\nThe first time you do this it will be expensive, since it will re-compute \nall the SHA1's in the .git/index file, but afterwards, it will be able to \nuse the index file to speed up operation, which is what is going to make \nthis all *much* cheaper than removing the old files and copying all the \nfiles around anew.\n\n(You can just force the re-indexing by doing a \"git status\" once, ie do\n\n\tcd /path/to/cvs/checkout_X\n\texport GIT_DIR=/path/to/git/repo\n\tgit status\n\nwhich will do it for you, and now all the subsequent snapshot generation \nshould be trivial and very fast).\n\nThe above is totally untested, of course, but I think that's the easiest \nway to do things like this. In general, it should be *trivial* to do \nsnapshots with git using just about _any_ legacy SCM, exactly because you \ncan keep the whole git setup away from the legacy SCM directories with \nthat \"GIT_DIR=..\" thing. \n\n(Of course, you could just move the .git directory into the CVS checkout \ntoo - and then CVS will just ignore it. But it may be a good idea to just \nkeep them explicitly separate).\n\n\t\t\tLinus\n"},{"id":"49125","messageId":"20070730192922.GB64467@nowhere","threadId":"9312","inReplyTo":"alpine.LFD.0.999.0707301144180.4161@woody.linux-foundation.org","subject":"Re: Efficient way to import snapshots?","fromName":"Craig Boston","fromEmail":"craig@olyun.gank.org","sentAt":"2007-07-30T19:29:23Z","receivedAt":"2007-07-30T19:29:23Z","isPatch":false,"sender":{"key":"craig@olyun.gank.org","avatar":null},"body":"On Mon, Jul 30, 2007 at 11:56:56AM -0700, Linus Torvalds wrote:\n> It should literally be as easy as doing something like\n> \n> \tcd /path/to/cvs/checkout_X\n> \texport GIT_DIR=/path/to/git/repo\n> \tgit add .\n> \tgit commit -m\"Import yyyymmdd snapshot\"\n\nAha!  I didn't know that you could point to a repository with GIT_DIR\nand do useful operations without a working directory.  My \"master\" repo\nthat gets backed up and cloned everywhere is a bare repo anyway; I had\nbeen cloning it with -s and then using 'git push' to get changes back\ninto it.\n\nA couple questions on that:\n\n1. Will it notice deleted files?\n2. How can I tell it what branch to commit to?\n\n> You'd have to make sure that you have the CVS directories ignored, of \n> course, and if you don't want to change the CVS directory at all (which is \n> a good idea!) you'd need to do that by using the \"ignore\" file in your \n> GIT_DIR, and just having the CVS entry there, instead of adding a\n> \".gitignore\" file to the working tree and checking it in.\n\nNot a problem, I'm using cvsup in checkout mode so there are no CVS\ndirs.  The checkout directory is an exact snapshot of \"What The\nRepository Should Look Like.\"\n\n> The above is totally untested, of course, but I think that's the easiest \n> way to do things like this. In general, it should be *trivial* to do \n> snapshots with git using just about _any_ legacy SCM, exactly because you \n> can keep the whole git setup away from the legacy SCM directories with \n> that \"GIT_DIR=..\" thing. \n\nI'll make a backup of my repo and give it a try.\n\nThanks!\n\nCraig\n"},{"id":"49130","messageId":"alpine.LFD.0.999.0707301240330.4161@woody.linux-foundation.org","threadId":"9312","inReplyTo":"20070730192922.GB64467@nowhere","subject":"Re: Efficient way to import snapshots?","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-07-30T19:52:52Z","receivedAt":"2007-07-30T19:52:52Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n[ Junio added, because I think I noticed a performance bug ]\n\nOn Mon, 30 Jul 2007, Craig Boston wrote:\n> \n> A couple questions on that:\n> \n> 1. Will it notice deleted files?\n\nYes, although I think you need to do \"git commit -a\" for that. \n\n\"git add .\" could (and perhaps _should_) notice them and remove them from \nthe cache, but doesn't. Whether that's the right behaviour or not (it does \nseem a bit strange that \"git add\" would actually remove files from the \nindex too) is up for debate.\n\nBut with \"git commit -a\", it will be noticed at commit time, at least.\n\nThat said, I just noticed something nasty: \"git add .\" is *horrible*. It \ndoes the full SHA1 re-computation even though the index is up-to-date. \nThat's really nasty.\n\nSo right now, due to this performance bug, it's actually much better to do \nsomething more complex, namely something like\n\n\tgit ls-files -o | git update-index --add --stdin\n\tgit commit -a\n\nwhich is a lot more efficient than just doing \"git add .\".\n\nJunio? I _thought_ we already took the index into account with \"git add\", \nbut we obviously don't. \n\n> 2. How can I tell it what branch to commit to?\n\nWhatever branch is checked out in the GIT_DIR will be the one that it \ncommits to.\n\n\t\t\tLinus\n"},{"id":"49131","messageId":"20070730201023.GC64467@nowhere","threadId":"9312","inReplyTo":"alpine.LFD.0.999.0707301240330.4161@woody.linux-foundation.org","subject":"Re: Efficient way to import snapshots?","fromName":"Craig Boston","fromEmail":"craig@olyun.gank.org","sentAt":"2007-07-30T20:10:23Z","receivedAt":"2007-07-30T20:10:23Z","isPatch":false,"sender":{"key":"craig@olyun.gank.org","avatar":null},"body":"On Mon, Jul 30, 2007 at 12:52:52PM -0700, Linus Torvalds wrote:\n> On Mon, 30 Jul 2007, Craig Boston wrote:\n> > 1. Will it notice deleted files?\n> \n> Yes, although I think you need to do \"git commit -a\" for that. \n\nAh, nice.  I had underestimated how smart git is, that was the whole\nreason I did the 'git rm -r .' dance at first :-)\n\n> > 2. How can I tell it what branch to commit to?\n> \n> Whatever branch is checked out in the GIT_DIR will be the one that it \n> commits to.\n\nHmm, ok.  I tried it out and it was unhappy with GIT_DIR pointing at the\nbare repository (no index file I presume), so I'll need a minimum of one\nclone.  With clone -s the repository itself shouldn't take up hardly any\nspace.  It sounds like my options are:\n\n1) Have a separate repository clone for each branch that I want to\nimport to and leave that branch permanently checked out.  I lose the\ndisk space for N working copies, but on the server I'm doing the import\non, it's not a huge issue, especially with ZFS compression ;-)\n\n * This might not actually be so bad if I put the .git directory inside\n   of the CVS checkout directory and used it as my \"working copy\".  I\n   just need to insure that git doesn't create any additional files in\n   there, as cvsup is really picky about not deleting files that it\n   didn't create, even if they were removed from CVS.\n\n2) Have one repository clone that gets re-used for each import, with the\n   \"checked out\" branch getting changed before the import.  As far as I can\n   tell this means suffering the \"git checkout\" overhead for 30,000 files,\n   which is conceptually inefficient but in real time only a minute or so.\n\n * Unless of course there's a way to forcibly change the state that the\n   repository thinks it's in without physically checking out the files.\n   I think it would still need to update index however.\n\n   I tried git reset --soft without success.  If this is possible, it\n   also makes option 1 more attractive if I can safely delete the\n   working copy files that it won't be using anyway.\n\nCraig\n"},{"id":"49136","messageId":"7vps29k3gm.fsf@assigned-by-dhcp.cox.net","threadId":"9312","inReplyTo":"alpine.LFD.0.999.0707301240330.4161@woody.linux-foundation.org","subject":"Re: Efficient way to import snapshots?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-07-30T21:04:57Z","receivedAt":"2007-07-30T21:04:57Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@linux-foundation.org> writes:\n\n> That said, I just noticed something nasty: \"git add .\" is *horrible*. It \n> does the full SHA1 re-computation even though the index is up-to-date. \n> That's really nasty.\n>\n> So right now, due to this performance bug, it's actually much better to do \n> something more complex, namely something like\n>\n> \tgit ls-files -o | git update-index --add --stdin\n> \tgit commit -a\n>\n> which is a lot more efficient than just doing \"git add .\".\n>\n> Junio? I _thought_ we already took the index into account with \"git add\", \n> but we obviously don't. \n\nI do not know offhand.\n\nBy the way, the above \"something more complex\" may be a simple\n\"git add -u\".\n"},{"id":"49141","messageId":"f8lkre$cme$1@sea.gmane.org","threadId":"9312","inReplyTo":"alpine.LFD.0.999.0707301144180.4161@woody.linux-foundation.org","subject":"Re: Efficient way to import snapshots?","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-07-30T21:22:54Z","receivedAt":"2007-07-30T21:22:54Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Linus Torvalds wrote:\n\n> On Mon, 30 Jul 2007, Craig Boston wrote:\n>> \n>> So far the main snag I've found is that AFAIK there's no equivalent to\n>> \"svk import\" to load a big tree (~37000 files) into a branch and commit\n>> the changes.  Here's the procedure I've come up with:\n>> \n>> cd /path/to/git/repo\n>> git checkout vendor_branch_X\n>> git rm -r .\n>> cp -R /path/to/cvs/checkout_X/* ./\n>> git add .\n>> git commit -m\"Import yyyymmdd snapshot\"\n> \n> Ouch.\n> \n> What you want to do should fit git very well, but doing it that way is \n> quite expensive.\n> \n> Might I suggest just doing the .git thing *directly* in the CVS checkout \n> instead?\n[...]\n\nAnd you can try to use git-fast-import. Check out\ncontrib/fast-import/import-tars.perl script (adapting it to your purpose).\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"49143","messageId":"7vabtdk2ch.fsf@assigned-by-dhcp.cox.net","threadId":"9312","inReplyTo":"20070730201023.GC64467@nowhere","subject":"Re: Efficient way to import snapshots?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-07-30T21:29:02Z","receivedAt":"2007-07-30T21:29:02Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Craig Boston <craig@olyun.gank.org> writes:\n\n> 1) Have a separate repository clone for each branch that I want to\n> import to and leave that branch permanently checked out.  I lose the\n> disk space for N working copies, but on the server I'm doing the import\n> on, it's not a huge issue, especially with ZFS compression ;-)\n>\n>  * This might not actually be so bad if I put the .git directory inside\n>    of the CVS checkout directory and used it as my \"working copy\".  I\n>    just need to insure that git doesn't create any additional files in\n>    there, as cvsup is really picky about not deleting files that it\n>    didn't create, even if they were removed from CVS.\n\nWith one of the projects hosted on CVS I have to interoperate\nwith, that is what I do.  For historical reasons I do not use\ngit-cvsimport/exportcommit for this one, but basically:\n\n - \"cvs co\" to prime the working tree;\n - \"echo CVS >.gitignore\";\n - \"git init && git add . && git commit\";\n - \"git checkout -b mine\";\n\nthen I work in \"mine\" branch.  When other people have something\nto say, I do:\n\n - \"git checkout master\";\n - \"cvs up\";\n - \"git add <whatever was added with the above cvs up>\";\n - \"git commit -a\";\n - \"git rebase master mine\";\n\nWhen feeding my own changes back to CVS, I would:\n\n - \"git checkout master\";\n - \"cvs up\" to make sure other people do not have any stuff;\n - \"git show-branch master mine\" to see what I have; \n\n - \"git cherry-pick <whatever the change I want to feed back>\";\n - \"cvs commit\";\n - repeat the last two steps for all the changes I want;\n\n - \"git rebase master mine\";\n\nI only need to make sure not to commit on \"master\", and not to\nrun \"cvs up\" while on \"mine\".\n\nThis can be extended to more than one CVS branches by using\ndifferent branches than \"master\".\n\n> 2) Have one repository clone that gets re-used for each import, with the\n>    \"checked out\" branch getting changed before the import.  As far as I can\n>    tell this means suffering the \"git checkout\" overhead for 30,000 files,\n>    which is conceptually inefficient but in real time only a minute or so.\n\nThat should only be \"conceptually\" in fact, as switching between\nbranches should not touch paths that are the same between\nbranches.\n"},{"id":"49153","messageId":"20070730214914.GD64467@nowhere","threadId":"9312","inReplyTo":"7vabtdk2ch.fsf@assigned-by-dhcp.cox.net","subject":"Re: Efficient way to import snapshots?","fromName":"Craig Boston","fromEmail":"craig@olyun.gank.org","sentAt":"2007-07-30T21:49:14Z","receivedAt":"2007-07-30T21:49:14Z","isPatch":false,"sender":{"key":"craig@olyun.gank.org","avatar":null},"body":"On Mon, Jul 30, 2007 at 02:29:02PM -0700, Junio C Hamano wrote:\n> Craig Boston <craig@olyun.gank.org> writes:\n> > 2) Have one repository clone that gets re-used for each import, with the\n> >    \"checked out\" branch getting changed before the import.  As far as I can\n> >    tell this means suffering the \"git checkout\" overhead for 30,000 files,\n> >    which is conceptually inefficient but in real time only a minute or so.\n> \n> That should only be \"conceptually\" in fact, as switching between\n> branches should not touch paths that are the same between\n> branches.\n\nI suspected as much, though in practice almost every file is different\nbetween the branches that I'm tracking.  RELENG_4 and RELENG_6 for\ninstance have years of development between them, with almost every major\nsubsystem and API reorganized in some way.\n\nI might have to do a quick compare once I get things imported and see\nexactly what the numbers are.\n\nCraig\n"},{"id":"49155","messageId":"854pjltv4z.fsf@lola.goethe.zz","threadId":"9312","inReplyTo":"20070730180710.GA64467@nowhere","subject":"Re: Efficient way to import snapshots?","fromName":"David Kastrup","fromEmail":"dak@gnu.org","sentAt":"2007-07-30T21:54:36Z","receivedAt":"2007-07-30T21:54:36Z","isPatch":false,"sender":{"key":"dak@gnu.org","avatar":"https://avatars.githubusercontent.com/u/52141349?v=4"},"body":"Craig Boston <craig@olyun.gank.org> writes:\n\n> So far the main snag I've found is that AFAIK there's no equivalent to\n> \"svk import\" to load a big tree (~37000 files) into a branch and commit\n> the changes.  Here's the procedure I've come up with:\n>\n> cd /path/to/git/repo\n> git checkout vendor_branch_X\n> git rm -r .\n> cp -R /path/to/cvs/checkout_X/* ./\n> git add .\n> git commit -m\"Import yyyymmdd snapshot\"\n\n\nI have not tried it, but shouldn't something like the following work?\n\ncd /path/to/cvs/checkout_X\ngit --git-dir=/path/to/git/repo/.git reset vendor_branch_X\ngit --git-dir=/path/to/git/repo/.git add .\ngit --git-dir=/path/to/git/repo/.git commit -a -m \"Import yyyymmdd snapshot\"\n\n\n-- \nDavid Kastrup, Kriemhildstr. 15, 44793 Bochum\n"},{"id":"49154","messageId":"7vy7gximkc.fsf@assigned-by-dhcp.cox.net","threadId":"9312","inReplyTo":"alpine.LFD.0.999.0707301240330.4161@woody.linux-foundation.org","subject":"Re: Efficient way to import snapshots?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-07-30T21:55:15Z","receivedAt":"2007-07-30T21:55:15Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@linux-foundation.org> writes:\n\n> Junio? I _thought_ we already took the index into account with \"git add\", \n> but we obviously don't. \n\nI think 366bfcb6 \"broke\" it by moving read_cache() call down,\nbecause it wanted the directory walking code to grab paths that\nare already in the index.  The change serves its purpose, but\nintroduces this regression now the responsibility of avoiding\nunnecessary reindexing by matching the cached stat is shifted\nnowhere.\n\nWe would need to do something like this patch, perhaps?  This\nfunction has three callers, two in builtin-add and another in\nbuiltin-mv.\n\n---\n read-cache.c  |    9 ++++++++-\n 1 files changed, 8 insertions(+), 1 deletions(-)\n\ndiff --git a/read-cache.c b/read-cache.c\nindex a363f31..c346d88 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -380,7 +380,7 @@ static int index_name_pos_also_unmerged(struct index_state *istate,\n \n int add_file_to_index(struct index_state *istate, const char *path, int verbose)\n {\n-\tint size, namelen;\n+\tint size, namelen, pos;\n \tstruct stat st;\n \tstruct cache_entry *ce;\n \n@@ -414,6 +414,13 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)\n \t\tce->ce_mode = ce_mode_from_stat(ent, st.st_mode);\n \t}\n \n+\tpos = index_name_pos(istate, ce->name, namelen);\n+\tif (0 <= pos && !ie_modified(istate, istate->cache[pos], &st, 1)) {\n+\t\t/* Nothing changed, really */\n+\t\tfree(ce);\n+\t\treturn 0;\n+\t}\n+\n \tif (index_path(ce->sha1, path, &st, 1))\n \t\tdie(\"unable to index file %s\", path);\n \tif (add_index_entry(istate, ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE))\n"},{"id":"49158","messageId":"20070730222028.GE64467@nowhere","threadId":"9312","inReplyTo":"alpine.LFD.0.999.0707301240330.4161@woody.linux-foundation.org","subject":"Re: Efficient way to import snapshots?","fromName":"Craig Boston","fromEmail":"craig@olyun.gank.org","sentAt":"2007-07-30T22:20:28Z","receivedAt":"2007-07-30T22:20:28Z","isPatch":false,"sender":{"key":"craig@olyun.gank.org","avatar":null},"body":"> \n> [ snip lots of helpful comments from various people ]\n> \n\nI just wanted to say thanks to Linus and Junio and everyone who\ncommented, I think I have a much more workable solution now.  With my\nbrute-force remove and re-add everything script the times for import\nlooked like this:\n\nImporting /compile/co/RELENG_4 (no changes):\nsvk import: 166.86 seconds\n       git: 455.82 seconds\n\nImporting /compile/co/RELENG_6:\nsvk import: 203.69 seconds\n       git: 796.48 seconds\n\nImporting /compile/co/HEAD:\nsvk import: 243.90 seconds\n       git: 837.13 seconds\n\nOk, so I remembered wrong, git was only 4x slower.  Still, I knew it\ncould do better than that...\n\nAfter transplanting the .git directory from 3 cloned repositories\nchecked out to the appropriate branch into the CVS checkout directories,\npriming them with a 'git status', and using the git ls-file | git\nupdate-index trick followed by commit -a, here are the revised times:\n\n# On branch cvs_RELENG_4\nnothing to commit (working directory clean)\ngit: 67.65 seconds\n\nCreated commit 106bc0b: Import 20070730 snapshot\n 7 files changed, 259 insertions(+), 75 deletions(-)\n Git repository at /compile/co/RELENG_6/src updated\ngit: 62.02 seconds\n\nCreated commit 776031b: Import 20070730 snapshot\n 86 files changed, 10929 insertions(+), 587 deletions(-)\n [snip lots of lines for added files]\n Git repository at /compile/co/HEAD/src updated\ngit: 61.77 seconds\n\n_MUCH_ better.  I knew it had to be capable of faster :-)\n\nAgain, thanks for all the help.  I look forward to seeing what else git\ncan do!\n\nCraig\n"},{"id":"49161","messageId":"alpine.LFD.0.999.0707301619080.4161@woody.linux-foundation.org","threadId":"9312","inReplyTo":"7vps29k3gm.fsf@assigned-by-dhcp.cox.net","subject":"Re: Efficient way to import snapshots?","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-07-30T23:19:28Z","receivedAt":"2007-07-30T23:19:28Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Mon, 30 Jul 2007, Junio C Hamano wrote:\n> \n> By the way, the above \"something more complex\" may be a simple\n> \"git add -u\".\n\nNo, that doesn't add new files, only already tracked ones.\n\n\t\tLinus\n"},{"id":"49163","messageId":"alpine.LFD.0.999.0707301624050.4161@woody.linux-foundation.org","threadId":"9312","inReplyTo":"7vy7gximkc.fsf@assigned-by-dhcp.cox.net","subject":"Re: Efficient way to import snapshots?","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-07-30T23:27:34Z","receivedAt":"2007-07-30T23:27:34Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Mon, 30 Jul 2007, Junio C Hamano wrote:\n> \n> We would need to do something like this patch, perhaps?  This\n> function has three callers, two in builtin-add and another in\n> builtin-mv.\n\nI think you need to check that ce is in stage 0 too.\n\n\t\tLinus\n"},{"id":"49164","messageId":"alpine.LFD.0.999.0707301629230.4161@woody.linux-foundation.org","threadId":"9312","inReplyTo":"20070730222028.GE64467@nowhere","subject":"Re: Efficient way to import snapshots?","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-07-30T23:30:22Z","receivedAt":"2007-07-30T23:30:22Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Mon, 30 Jul 2007, Craig Boston wrote:\n> \n> # On branch cvs_RELENG_4\n> nothing to commit (working directory clean)\n> git: 67.65 seconds\n\nSo I _seriously_ hope that about 65 of those 67 seconds was the \"cvs \nupdate -d\" or something like that. \n\nAnything that takes a minute in git is way way *way* too slow. Any \nhalf-way normal git operations should take less than a second.\n\n\t\tLinus\n"},{"id":"49165","messageId":"7vsl75igtt.fsf@assigned-by-dhcp.cox.net","threadId":"9312","inReplyTo":"alpine.LFD.0.999.0707301624050.4161@woody.linux-foundation.org","subject":"Re: Efficient way to import snapshots?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-07-30T23:59:10Z","receivedAt":"2007-07-30T23:59:10Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@linux-foundation.org> writes:\n\n> On Mon, 30 Jul 2007, Junio C Hamano wrote:\n>> \n>> We would need to do something like this patch, perhaps?  This\n>> function has three callers, two in builtin-add and another in\n>> builtin-mv.\n>\n> I think you need to check that ce is in stage 0 too.\n\nI guess so, but can higher stage entries have cached stat\ninformation that are valid and match the working tree?\n\n---\n read-cache.c  |   11 ++++++++++-\n 1 files changed, 10 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin-add.c b/builtin-add.c\ndiff --git a/read-cache.c b/read-cache.c\nindex a363f31..9c00ccb 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -380,7 +380,7 @@ static int index_name_pos_also_unmerged(struct index_state *istate,\n \n int add_file_to_index(struct index_state *istate, const char *path, int verbose)\n {\n-\tint size, namelen;\n+\tint size, namelen, pos;\n \tstruct stat st;\n \tstruct cache_entry *ce;\n \n@@ -414,6 +414,15 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)\n \t\tce->ce_mode = ce_mode_from_stat(ent, st.st_mode);\n \t}\n \n+\tpos = index_name_pos(istate, ce->name, namelen);\n+\tif (0 <= pos && \n+\t    !ce_stage(istate->cache[pos]) &&\n+\t    !ie_modified(istate, istate->cache[pos], &st, 1)) {\n+\t\t/* Nothing changed, really */\n+\t\tfree(ce);\n+\t\treturn 0;\n+\t}\n+\n \tif (index_path(ce->sha1, path, &st, 1))\n \t\tdie(\"unable to index file %s\", path);\n \tif (add_index_entry(istate, ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE))\n"},{"id":"49169","messageId":"alpine.LFD.0.999.0707301744050.4161@woody.linux-foundation.org","threadId":"9312","inReplyTo":"7vsl75igtt.fsf@assigned-by-dhcp.cox.net","subject":"Re: Efficient way to import snapshots?","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-07-31T00:45:26Z","receivedAt":"2007-07-31T00:45:26Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Mon, 30 Jul 2007, Junio C Hamano wrote:\n> \n> I guess so, but can higher stage entries have cached stat\n> information that are valid and match the working tree?\n\nProbably unlikely, but I could imagine that it's the case for things that \nfailed to merge entirely (ie binaries), where you end up just saying \"pick \nthe old/base binary\", and it ends up matching in stage1.\n\n\t\tLinus\n"},{"id":"49171","messageId":"7vfy35iekl.fsf@assigned-by-dhcp.cox.net","threadId":"9312","inReplyTo":"alpine.LFD.0.999.0707301744050.4161@woody.linux-foundation.org","subject":"Re: Efficient way to import snapshots?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-07-31T00:47:54Z","receivedAt":"2007-07-31T00:47:54Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@linux-foundation.org> writes:\n\n> On Mon, 30 Jul 2007, Junio C Hamano wrote:\n>> \n>> I guess so, but can higher stage entries have cached stat\n>> information that are valid and match the working tree?\n>\n> Probably unlikely, but I could imagine that it's the case for things that \n> failed to merge entirely (ie binaries), where you end up just saying \"pick \n> the old/base binary\", and it ends up matching in stage1.\n\nProbably.  In any case, what I'll commit will have the stage#0\ncheck, just to be safe anyway.\n\nThanks for the sanity.  Really appreciate it.\n"},{"id":"49173","messageId":"20070731011707.GA91930@nowhere","threadId":"9312","inReplyTo":"alpine.LFD.0.999.0707301629230.4161@woody.linux-foundation.org","subject":"Re: Efficient way to import snapshots?","fromName":"Craig Boston","fromEmail":"craig@olyun.gank.org","sentAt":"2007-07-31T01:17:07Z","receivedAt":"2007-07-31T01:17:07Z","isPatch":false,"sender":{"key":"craig@olyun.gank.org","avatar":null},"body":"On Mon, Jul 30, 2007 at 04:30:22PM -0700, Linus Torvalds wrote:\n> > # On branch cvs_RELENG_4\n> > nothing to commit (working directory clean)\n> > git: 67.65 seconds\n> \n> So I _seriously_ hope that about 65 of those 67 seconds was the \"cvs \n> update -d\" or something like that. \n\nNo, the only thing included in that is\n\ngit ls-files -o | git update-index --add --stdin\ngit commit -a -m \"${COMMITMSG}\"\n\n> Anything that takes a minute in git is way way *way* too slow. Any \n> half-way normal git operations should take less than a second.\n\nThat said, I don't think it's git's fault.  I think most of the time is\nspent calling stat() on all the files.  The machine that took 60 seconds\nisn't what I'd call top-of-the-line:\n\n1st or maybe 2nd-gen Willamette CPU\n512MB memory (stupid motherboard that won't accept more)\nSlow disks in RAID-5 configuration\nRunning ZFS with less than half of the recommended minimum memory, to\nthe point where I had to reduce the number of vnodes that the kernel is\nallowed to cache to avoid running out of KVA\n\nA simple find(1) over the CVS checkout directory takes almost as long.\nI don't think it has enough memory to cache the whole thing.  Actually I\nknow it can't since maxvnodes is set to 25,000 and there's 37,000 files\nin the cvs checkout, so it will have to pull some directory entries from\ndisk regardless.\n\nJust to be sure, I copied the cvs checkout directory and git repository\nto a newer, faster dual-core machine with plenty of memory available for\ncaching.\n\nThe first run of 'git status' (cold cache):\ngit status  1.08s user 3.68s system 13% cpu 34.043 total\n\nThe second run:\ngit status  1.05s user 2.68s system 85% cpu 4.373 total\n\nBased on that I'm fairly confident that most of the 60 seconds is being\nspent waiting on data from the disks.  On a tmpfs filesystem I can get\nit even faster (1.897 seconds)\n\nAs it's a file server for which network is the usual bottleneck, and all\nthe git operations will be running out of cron, I'm not too worried\nabout it.\n\nCraig\n"},{"id":"49179","messageId":"alpine.LFD.0.999.0707301825130.4161@woody.linux-foundation.org","threadId":"9312","inReplyTo":"20070731011707.GA91930@nowhere","subject":"Re: Efficient way to import snapshots?","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-07-31T01:44:13Z","receivedAt":"2007-07-31T01:44:13Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Mon, 30 Jul 2007, Craig Boston wrote:\n> > \n> > So I _seriously_ hope that about 65 of those 67 seconds was the \"cvs \n> > update -d\" or something like that. \n> \n> No, the only thing included in that is\n> \n> git ls-files -o | git update-index --add --stdin\n> git commit -a -m \"${COMMITMSG}\"\n\nOuch.\n\n> > Anything that takes a minute in git is way way *way* too slow. Any \n> > half-way normal git operations should take less than a second.\n> \n> That said, I don't think it's git's fault.  I think most of the time is\n> spent calling stat() on all the files.  The machine that took 60 seconds\n> isn't what I'd call top-of-the-line:\n> \n> 1st or maybe 2nd-gen Willamette CPU\n> 512MB memory (stupid motherboard that won't accept more)\n> Slow disks in RAID-5 configuration\n> Running ZFS with less than half of the recommended minimum memory, to\n> the point where I had to reduce the number of vnodes that the kernel is\n> allowed to cache to avoid running out of KVA\n\nOh, ok. Solaris.\n\nWith slow pathname lookup, and hard limits on the inode cache sizes.\n\nGit really normally avoids reading the data, so even in 512M you should \n_easily_ be able to cache the metadata (directory and inodes), which is \nall you need. But yeah, Linux will probably do that a whole lot more \naggressively than Solaris does.\n\n[ And to be honest, any CVS update would probably have blown the caches on \n  Linux too - I don't know what all CVS ends up doing, but from past\n  experience, I'll bet it's not good ]\n\nBut just for comparison, on a lowly 480MB mac-mini (running Linux, not OS \nX, of course - and the 480MB is because the graphics is UMA and takes \npart of the 512MB total), and the kernel archive (which is just 22k files, \nnot 37k), with a laptop drive:\n\n - cold-cache \"git status\":\n\treal    0m17.975s\n\tuser    0m1.098s\n\tsys     0m0.539s\n\n - rerunning it immediately afterwards:\n\treal    0m1.079s\n\tuser    0m0.896s\n\tsys     0m0.183s\n\nso the target really _should_ generally be one second.\n\nBut yeah, in order to hit that target, you definitely do want to keep the \nmetadata cached, and I guess that means more than 512M on Solaris.\n\n\t\t\tLinus\n"},{"id":"49191","messageId":"20070731042347.GG25876@thunk.org","threadId":"9312","inReplyTo":"alpine.LFD.0.999.0707301825130.4161@woody.linux-foundation.org","subject":"Re: Efficient way to import snapshots?","fromName":"Theodore Tso","fromEmail":"tytso@mit.edu","sentAt":"2007-07-31T04:23:47Z","receivedAt":"2007-07-31T04:23:47Z","isPatch":false,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Mon, Jul 30, 2007 at 06:44:13PM -0700, Linus Torvalds wrote:\n> > 1st or maybe 2nd-gen Willamette CPU\n> > 512MB memory (stupid motherboard that won't accept more)\n> > Slow disks in RAID-5 configuration\n> > Running ZFS with less than half of the recommended minimum memory, to\n> > the point where I had to reduce the number of vnodes that the kernel is\n> > allowed to cache to avoid running out of KVA\n> \n> Oh, ok. Solaris.\n> \n> With slow pathname lookup, and hard limits on the inode cache sizes.\n> \n> Git really normally avoids reading the data, so even in 512M you should \n> _easily_ be able to cache the metadata (directory and inodes), which is \n> all you need. But yeah, Linux will probably do that a whole lot more \n> aggressively than Solaris does.\n\nI also have a suspicion that ZFS's \"never overwrite metadata\" is\ncausing its inodes to be be scattered all over the disk, so the lack\nof cacheing is hurting even more than it would for other filesystems.\n(Put another way, there's probably a really good reason for ZFS's\nminimum memory recommendations.)\n\nCraig, it might be interesting to see what sort of results you get if\nyou use UFS instead of ZFS in your low-memory constrained\nenvironment...\n\n\t\t\t\t\t\t- Ted\n"},{"id":"49195","messageId":"85odht3xd1.fsf@lola.goethe.zz","threadId":"9312","inReplyTo":"alpine.LFD.0.999.0707301629230.4161@woody.linux-foundation.org","subject":"Re: Efficient way to import snapshots?","fromName":"David Kastrup","fromEmail":"dak@gnu.org","sentAt":"2007-07-31T06:23:22Z","receivedAt":"2007-07-31T06:23:22Z","isPatch":false,"sender":{"key":"dak@gnu.org","avatar":"https://avatars.githubusercontent.com/u/52141349?v=4"},"body":"Linus Torvalds <torvalds@linux-foundation.org> writes:\n\n> On Mon, 30 Jul 2007, Craig Boston wrote:\n>> \n>> # On branch cvs_RELENG_4\n>> nothing to commit (working directory clean)\n>> git: 67.65 seconds\n>\n> So I _seriously_ hope that about 65 of those 67 seconds was the \"cvs \n> update -d\" or something like that. \n>\n> Anything that takes a minute in git is way way *way* too slow. Any \n> half-way normal git operations should take less than a second.\n\nI tried a git-add . on a TeX live tree (lots of itsy files).  About\n80% of the processor time was wait.\n\nI think that SHA1 is costly enough that the processor(s) could get\nsaturated when enough is done in parallel.\n\nPotential for multithreading is here enough to make any Summer of Code\nstudent weep with joy:\n\na) one thread for opendir/readdir at every directory level\nb) one thread for stating the files in readdir order (more likely to\n   correspond to the disk layout than sorted order)\nc) one thread on each directory level doing a mergesort on a different\n   link field (some merge passes could be parallelized even, but let's\n   not get overexcited)\nd) asynch I/O requesting the data for all files to be submitted to\n   SHA1\ne) one thread (but no more threads than there are CPUs) per\n   independent file/tree for doing SHA1\nf) asynch I/O reading the index sequentially\ng) one thread doing a merge pass of already sorted stuff (this can\n   start once the top level directory has been read and sorted\n   completely, possibly having to stop until a complete subdirectory\n   comes in).\nh) asynch I/O writing out the results of the merge sequentially\n\nIn fact, git-ls-files|git-add --stdin is already exploiting a bit of\nparallelism (and will probably profit from CFS by making much more use\nof the buffering capacity of the pipe).  It is counterintuitive that\nhand-built chains work more efficiently than explicit git commands.\n\n-- \nDavid Kastrup, Kriemhildstr. 15, 44793 Bochum\n"},{"id":"49198","messageId":"87r6mpj9dd.fsf@mid.deneb.enyo.de","threadId":"9312","inReplyTo":"85odht3xd1.fsf@lola.goethe.zz","subject":"Re: Efficient way to import snapshots?","fromName":"Florian Weimer","fromEmail":"fw@deneb.enyo.de","sentAt":"2007-07-31T07:54:54Z","receivedAt":"2007-07-31T07:54:54Z","isPatch":false,"sender":{"key":"fw@deneb.enyo.de","avatar":null},"body":"* David Kastrup:\n\n> a) one thread for opendir/readdir at every directory level\n> b) one thread for stating the files in readdir order (more likely to\n>    correspond to the disk layout than sorted order)\n\nNot true for ext3.  You need to sort by the d_ino field.  This also\ntends to be benefit other file systems more than readdir order.\n"},{"id":"49200","messageId":"867iohq7q1.fsf@lola.quinscape.zz","threadId":"9312","inReplyTo":"87r6mpj9dd.fsf@mid.deneb.enyo.de","subject":"Re: Efficient way to import snapshots?","fromName":"David Kastrup","fromEmail":"dak@gnu.org","sentAt":"2007-07-31T08:48:38Z","receivedAt":"2007-07-31T08:48:38Z","isPatch":false,"sender":{"key":"dak@gnu.org","avatar":"https://avatars.githubusercontent.com/u/52141349?v=4"},"body":"Florian Weimer <fw@deneb.enyo.de> writes:\n\n> * David Kastrup:\n>\n>> a) one thread for opendir/readdir at every directory level\n>> b) one thread for stating the files in readdir order (more likely to\n>>    correspond to the disk layout than sorted order)\n>\n> Not true for ext3.  You need to sort by the d_ino field.  This also\n> tends to be benefit other file systems more than readdir order.\n\nUh, yes, for stating it would (I actually though alphabetic sort order\nhere, and that would not likely help).  So we just introduce another\nthread a2) that sorts the partial list from a) as long as b) is still\nbusy stating...  But I guess that a2) would be a thread that will\nlikely not cause much of a speedup.\n\n-- \nDavid Kastrup\n"},{"id":"49223","messageId":"20070731135332.GA58867@nowhere","threadId":"9312","inReplyTo":"20070731042347.GG25876@thunk.org","subject":"Re: Efficient way to import snapshots?","fromName":"Craig Boston","fromEmail":"craig@olyun.gank.org","sentAt":"2007-07-31T13:53:32Z","receivedAt":"2007-07-31T13:53:32Z","isPatch":false,"sender":{"key":"craig@olyun.gank.org","avatar":null},"body":"On Tue, Jul 31, 2007 at 12:23:47AM -0400, Theodore Tso wrote:\n> On Mon, Jul 30, 2007 at 06:44:13PM -0700, Linus Torvalds wrote:\n> > \n> > Oh, ok. Solaris.\n\nFor reference, as I mentioned to Linus & Junio in an excessively\nverbose, and probably uninteresting to most of the git-list members,\nmessage about the performance characteristics of ZFS, I'm actually\nrunning FreeBSD-current with the experimental port of ZFS.\n\nSo, even less tested & tuned than it is on Solaris.  Part of what I'm\ndoing is stress testing the filesystem on machines with less than the\nrecommended memory.  Even if performance is suboptimal, it should at\nleast not break anything.\n\n> Craig, it might be interesting to see what sort of results you get if\n> you use UFS instead of ZFS in your low-memory constrained\n> environment...\n\nI just so happen to be rebuilding the zfs pool on that server this\nmorning in order to add more swap, so your wish(1tcl) is my rcmd(3).\n\nSame machine, on a UFS filesystem (single disk, since zfs was doing the\nRAID), with the cache tuning parameters reset back to defaults:\n\nFirst 'git status' after a reboot:\ngit status  2.23s user 2.23s system 17% cpu 24.987 total\n\nSecond:\ngit status  1.81s user 1.34s system 98% cpu 3.188 total\n\nThird:\ngit status  1.76s user 1.45s system 98% cpu 3.252 total\n\nSo I definitely think the problem is just that with its increased\noverhead, ZFS simply can't keep all the metadata in the cache with the\navailable memory.\n\nCraig\n"},{"id":"49233","messageId":"alpine.LFD.0.999.0707310845490.4161@woody.linux-foundation.org","threadId":"9312","inReplyTo":"20070731135332.GA58867@nowhere","subject":"Re: Efficient way to import snapshots?","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-07-31T15:50:19Z","receivedAt":"2007-07-31T15:50:19Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Tue, 31 Jul 2007, Craig Boston wrote:\n> \n> I just so happen to be rebuilding the zfs pool on that server this\n> morning in order to add more swap, so your wish(1tcl) is my rcmd(3).\n\nYou, sir, are a total geek.\n\nI'm not sure if that's a compliment or a curse.\n\n> Same machine, on a UFS filesystem (single disk, since zfs was doing the\n> RAID), with the cache tuning parameters reset back to defaults:\n> \n> First 'git status' after a reboot:\n> git status  2.23s user 2.23s system 17% cpu 24.987 total\n> \n> Second:\n> git status  1.81s user 1.34s system 98% cpu 3.188 total\n> \n> Third:\n> git status  1.76s user 1.45s system 98% cpu 3.252 total\n> \n> So I definitely think the problem is just that with its increased\n> overhead, ZFS simply can't keep all the metadata in the cache with the\n> available memory.\n\nVery interesting. And thanks. The whole \"ZFS is great\" internet meme seems \nto be partly due to not a lot of people having used or compared it in real \nlife. I'm sure it's wonderful for some things, but it clearly does have a \nlot of downsides too. \n\n\t\t\tLinus\n"},{"id":"49234","messageId":"20070731161524.GA28645@thunk.org","threadId":"9312","inReplyTo":"alpine.LFD.0.999.0707310845490.4161@woody.linux-foundation.org","subject":"Re: Efficient way to import snapshots?","fromName":"Theodore Tso","fromEmail":"tytso@mit.edu","sentAt":"2007-07-31T16:15:24Z","receivedAt":"2007-07-31T16:15:24Z","isPatch":false,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Tue, Jul 31, 2007 at 08:50:19AM -0700, Linus Torvalds wrote:\n> Very interesting. And thanks. The whole \"ZFS is great\" internet meme seems \n> to be partly due to not a lot of people having used or compared it in real \n> life. I'm sure it's wonderful for some things, but it clearly does have a \n> lot of downsides too. \n\nI'm pretty sure Sun's marketing machine is also very much part of it;\nI'm not convinced all of the blogs pitching ZFS as the most wonderful\nthing since sliced bread were all, shall we say, unbiased or\nuninfluenced by Sun.  Add to that the fact that the Solaris 10 License\nAgreement prohibits you from publishing benchmark numbers without\nSun's permisison, and it's not at all surprising that most of what\npeople have heard of ZFS has all been the positive stuff.  But with\nmore people playing with ZFS in the FreeBSD and OpenSolaris camps, I'm\nsure a more balanced view that shows its advantages *and*\ndisadvantages will start showing up.\n\n            \t    \t     \t       - Ted\n"}]}