{"thread":{"id":"4995","subject":"Re: Nasty git corruption problem","startedAt":"2006-07-26T15:57:03Z","lastAt":"2006-07-26T17:07:07Z","messageCount":2,"participants":["Paolo Ciarrocchi","Linus Torvalds"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"24139","messageId":"4d8e3fd30607260857v17bde4afqbe68fde583d2f15f@mail.gmail.com","threadId":"4995","inReplyTo":"1153929715.13509.12.camel@localhost.localdomain","subject":"Re: Nasty git corruption problem","fromName":"Paolo Ciarrocchi","fromEmail":"paolo.ciarrocchi@gmail.com","sentAt":"2006-07-26T15:57:03Z","receivedAt":"2006-07-26T15:57:03Z","isPatch":false,"sender":{"key":"paolo.ciarrocchi@gmail.com","avatar":null},"body":"Just added the git ML where you can have better support for this problem.\n\n\nOn 7/26/06, Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:\n> Just hit a real nasty, although I suspect its not a common case but it\n> does seem to show a problem git has other version control systems don't\n> (so far anyway)\n>\n> During a git rebase my machine crashed. Git claims that the rebase is\n> complete but contains none of the outstanding 30 odd patches. There is\n> no .dotest directory and git-fsck-objects produces some warnings about a\n> few dangling objects, but these objects aren't the relevant ones (at\n> least directly)\n>\n> CVS and SVN in crashes don't lose old stuff, though they are pretty good\n> at losing the last commit or two. Git rebase appears to be able to lose\n> two weeks of old changes even though they were stable on disk, which is\n> not good at all.\n>\n> Doing\n>\n> for i in *; do (cd $i; for j in *; do git-unpack-file $i$j; done; );\n> done\n>\n> shows that lots of the changes are still somewhere in the object tree\n> but there seems to be no tool for fixing rather than moaning about\n> objects dangling, and also no obvious way to fix it. Also curiously many\n> of the objects appear linked somewhere but don't show up in the git-log\n> for the afflicted branch at all.\n>\n>\n>\n>\n>\n>\n> -\n> To unsubscribe from this list: send the line \"unsubscribe linux-kernel\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n> Please read the FAQ at  http://www.tux.org/lkml/\n>\n\n\n-- \nPaolo\nhttp://paolo.ciarrocchi.googlepages.com\nhttp://picasaweb.google.com/paolo.ciarrocchi\n"},{"id":"24141","messageId":"Pine.LNX.4.64.0607260945440.29649__37133.1703653142$1153933936$gmane$org@g5.osdl.org","threadId":"4995","inReplyTo":"1153929715.13509.12.camel@localhost.localdomain","subject":"Re: Nasty git corruption problem","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-07-26T17:07:07Z","receivedAt":"2006-07-26T17:07:07Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Wed, 26 Jul 2006, Alan Cox wrote:\n> \n> During a git rebase my machine crashed. Git claims that the rebase is \n> complete but contains none of the outstanding 30 odd patches. There is \n> no .dotest directory and git-fsck-objects produces some warnings about a \n> few dangling objects, but these objects aren't the relevant ones (at \n> least directly)\n\nThey definitely should be, unless you actually did a \"git prune\" (or a \n\"git repack -d\").\n\n> CVS and SVN in crashes don't lose old stuff, though they are pretty good\n> at losing the last commit or two.\n\nAnd git should be even harder to get to lose old stuff, because it won't \neven touch it. \n\n> Doing\n> \n> for i in *; do (cd $i; for j in *; do git-unpack-file $i$j; done; );\n> done\n> \n> shows that lots of the changes are still somewhere in the object tree\n> but there seems to be no tool for fixing rather than moaning about\n> objects dangling, and also no obvious way to fix it.\n\nWell, the \"dangling objects\" really should be the fix. We could make it \neven more obvious by creating links to the dangling objects in a \n\"lost+found\" directory, but I usually just do it by hand.\n\nSo the thing to do to recover any old stuff is\n\n - do \"git-fsck-objects --full\".\n\n   The \"--full\" is going to make it much slower, but it means that it will \n   look _inside_ old packs too, and if you repacked the old stuff, that's \n   what you want. Besides, if you actually had a real crash in the middle \n   of a git op, you probably do want this anyway, although quite frankly, \n   a truly corrupted pack is pretty damn unlikely (the only case I \n   remember ever seing was due to actual hardware problems)\n\n   I _suspect_ you didn't do the \"--full\". By default, git-fsck-objects \n   will only look at the unpacked objects, exactly because pack-files are \n   so stable. So the only reason to use \"--full\" is if you're really anal \n   and suspect hw issues, _or_ if you are looking for dangling work that \n   may be older than your last repack.\n\n - take all the dangling objects, and either list them explicitly to \n   \"gitk\" (or other visualizer), or you could save them off as\n\n\t.git/refs/lost+found/<some-random-names-here>\n\n   and then do \"gitk --all\"\n\nIn fact, if you want to play around with a git patch, this trivial one \nshould make git-fsck-objects create those lost-and-found entries \nautomatically if you give it the \"--lost-n-found\" flag.\n\nAnyway, I'm pretty sure that git is a hell of a lot _safer_ than either \nCVS or SVN have ever been, or will ever be.\n\n\t\tLinus\n\n---\ndiff --git a/fsck-objects.c b/fsck-objects.c\nindex e167f41..fa50190 100644\n--- a/fsck-objects.c\n+++ b/fsck-objects.c\n@@ -14,6 +14,7 @@ #include \"tree-walk.h\"\n #define REACHABLE 0x0001\n #define SEEN      0x0002\n \n+static int lost_and_found = 0;\n static int show_root = 0;\n static int show_tags = 0;\n static int show_unreachable = 0;\n@@ -102,8 +103,23 @@ static void check_connectivity(void)\n \t\t}\n \n \t\tif (!obj->used) {\n-\t\t\tprintf(\"dangling %s %s\\n\", typename(obj->type),\n-\t\t\t       sha1_to_hex(obj->sha1));\n+\t\t\tchar *hex = sha1_to_hex(obj->sha1);\n+\t\t\tprintf(\"dangling %s %s\\n\", typename(obj->type), hex);\n+\t\t\tif (lost_and_found) {\n+\t\t\t\tint fd, ret;\n+\t\t\t\tmkdir(git_path(\"refs/lost+found\"), 0777);\n+\t\t\t\tfd = open(git_path(\"refs/lost+found/%s\", hex), O_CREAT | O_TRUNC | O_WRONLY, 0666);\n+\t\t\t\tif (fd < 0) {\n+\t\t\t\t\tperror(\"lost+found\");\n+\t\t\t\t\tcontinue;\n+\t\t\t\t}\n+\t\t\t\thex[40] = '\\n';\n+\t\t\t\tret = xwrite(fd, hex, 41);\n+\t\t\t\tclose(fd);\n+\t\t\t\tif (ret != 41)\n+\t\t\t\t\terror(\"unable to write to lost+found\");\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t}\n \t}\n }\n@@ -514,6 +530,10 @@ int main(int argc, char **argv)\n \t\t\tcheck_strict = 1;\n \t\t\tcontinue;\n \t\t}\n+\t\tif (!strcmp(arg, \"--lost-n-found\")) {\n+\t\t\tlost_and_found = 1;\n+\t\t\tcontinue;\n+\t\t}\n \t\tif (*arg == '-')\n \t\t\tusage(\"git-fsck-objects [--tags] [--root] [[--unreachable] [--cache] [--full] [--strict] <head-sha1>*]\");\n \t}\n"}]}