{"thread":{"id":"9335","subject":"dangling blob which is not dangling at all","startedAt":"2007-08-01T01:34:50Z","lastAt":"2007-08-01T14:21:39Z","messageCount":8,"participants":["Domenico Andreoli","Linus Torvalds","Junio C Hamano","Steven Grimm","Rogan Dawes"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"49267","messageId":"20070801013450.GA16498@raptus.dandreoli.com","threadId":"9335","inReplyTo":null,"subject":"dangling blob which is not dangling at all","fromName":"Domenico Andreoli","fromEmail":"cavokz@gmail.com","sentAt":"2007-08-01T01:34:50Z","receivedAt":"2007-08-01T01:34:50Z","isPatch":false,"sender":{"key":"cavokz@gmail.com","avatar":null},"body":"Hi,\n\n  first of all, I want to thank Linus and you all for git, it is\nrevolutionizing my every-day work flow. Exceptional.\n\nPlaying with my central bare git repository (yes, I am a former\nCVS/SVN user) and trying to lose data I discovered something I am not\nunderstanding well.\n\nRunning git fsck --no-reflogs I found some dangling objects (I have\nto say I enjoyed a lot in navigating commits, trees and blobs with\nplumbing... really!), two were commits and one was a blob.\n\nOne of the commits was there because I pushed (forcing) from a working\nrepository after a git reset HEAD^. I checked it and removed it and\nall the other dependant objects until the blob which contained the new\nversion of that file. It seems I even understood what I was doing! ;)\nUntil here, everything had been smooth.\n\nSecond commit was something pushed from another repository but at the\nright head was strangely recorded with a different hash. Removing it,\nits tree and another sub-tree, no blob was pending. So the final blob\ncontaining the change was still used elsewhere, indeed by the \"right\nhead\" of above. While I would expect this in a working repository where\nmerging is happening all the day, it is not clear how it happened to\nmy central repository, where nobody does any work. Any idea?\n\nAnd now, what I think is a bug, the dangling blob. It is signaled as\ndangling but it is not. Hunting for a commit/tree/blob to compare it to\nin order to understand which modification it was hiding, I found a tree\nobject which referred to it, which by definition of \"dangling object\"\nshould not exist. So fsck looks f*cked... and I am well available to\nunderstand what is going wrong here, but please help me.\n\n$ git fsck --no-reflogs\ndangling blob e5d444e61b834c34710ce8fb5cb176e20e5894e1\n$ git-ls-tree 70b58535361eb633d44d4f1275af3421ca6a5ed7\n...\n100644 blob e5d444e61b834c34710ce8fb5cb176e20e5894e1    link_stream.c\n...\n\nIf you read me until here, good night! ;)\n\nCheers,\nDomenico\n\n-----[ Domenico Andreoli, aka cavok\n --[ http://www.dandreoli.com/gpgkey.asc\n   ---[ 3A0F 2F80 F79C 678A 8936  4FEE 0677 9033 A20E BC50\n"},{"id":"49270","messageId":"alpine.LFD.0.999.0707311914570.4161@woody.linux-foundation.org","threadId":"9335","inReplyTo":"20070801013450.GA16498@raptus.dandreoli.com","subject":"Re: dangling blob which is not dangling at all","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-08-01T02:22:14Z","receivedAt":"2007-08-01T02:22:14Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Wed, 1 Aug 2007, Domenico Andreoli wrote:\n> \n> $ git fsck --no-reflogs\n> dangling blob e5d444e61b834c34710ce8fb5cb176e20e5894e1\n>\n> $ git-ls-tree 70b58535361eb633d44d4f1275af3421ca6a5ed7\n> ...\n> 100644 blob e5d444e61b834c34710ce8fb5cb176e20e5894e1    link_stream.c\n\nHave you done clones with stupid protocols (rsync and/or http)?\n\nThe simplest explanation for this is that since you didn't do \"--full\" for \nfsck, then your git-fsck never looked into the pack-files you had. And the \ntree might well exist in a pack-file, and thus not even looked at by fsck.\n\nSo try \"git fsck --full\", and see if that changes the picture.\n\n(Usually, you'd never have a pack-file *and* the loose object it points to \nboth at the same time, but especially if you use the dumb transports \n(rsync and/or http), you'll get pack-files from remotes, and thus you \nwon't have the normal nice behaviour of pack-files being \"old state\", and \nloose objects being \"new state\".\n\nThe easiest fixup is likely to just do \"git gc\", which which do a nice \nrepack, and get rid of loose objects that are duplicates of stuff \nthat is also in a pack-file.\n\n\t\tLinus\n"},{"id":"49284","messageId":"20070801063209.GA13511@raptus.dandreoli.com","threadId":"9335","inReplyTo":"alpine.LFD.0.999.0707311914570.4161@woody.linux-foundation.org","subject":"Re: dangling blob which is not dangling at all","fromName":"Domenico Andreoli","fromEmail":"cavokz@gmail.com","sentAt":"2007-08-01T06:32:09Z","receivedAt":"2007-08-01T06:32:09Z","isPatch":false,"sender":{"key":"cavokz@gmail.com","avatar":null},"body":"On Tue, Jul 31, 2007 at 07:22:14PM -0700, Linus Torvalds wrote:\n> \n> \n> On Wed, 1 Aug 2007, Domenico Andreoli wrote:\n> > \n> > $ git fsck --no-reflogs\n> > dangling blob e5d444e61b834c34710ce8fb5cb176e20e5894e1\n> >\n> > $ git-ls-tree 70b58535361eb633d44d4f1275af3421ca6a5ed7\n> > ...\n> > 100644 blob e5d444e61b834c34710ce8fb5cb176e20e5894e1    link_stream.c\n> \n> Have you done clones with stupid protocols (rsync and/or http)?\n\nI do not remember having used any dump transport on this repository but\nI recall having tried git-repack with the intent of git gc.\n\n> So try \"git fsck --full\", and see if that changes the picture.\n\nThis did not change anything.\n\n> The easiest fixup is likely to just do \"git gc\", which which do a nice \n> repack, and get rid of loose objects that are duplicates of stuff \n> that is also in a pack-file.\n\nThis fixed things and also warned about two heads referring to pruned\ncommits, which may be those two commits I removed by hand (I hope).\n\nCheers,\nDomenico\n\n-----[ Domenico Andreoli, aka cavok\n --[ http://www.dandreoli.com/gpgkey.asc\n   ---[ 3A0F 2F80 F79C 678A 8936  4FEE 0677 9033 A20E BC50\n"},{"id":"49285","messageId":"7vhcnjbtpt.fsf@assigned-by-dhcp.cox.net","threadId":"9335","inReplyTo":"20070801063209.GA13511@raptus.dandreoli.com","subject":"Re: dangling blob which is not dangling at all","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-08-01T07:27:10Z","receivedAt":"2007-08-01T07:27:10Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Domenico Andreoli <cavokz@gmail.com> writes:\n\n> This fixed things and also warned about two heads referring to pruned\n> commits, which may be those two commits I removed by hand (I hope).\n\nExactly.\n\nAll refs under .git/refs (the special case of this includes the\nbranch heads in .git/refs/heads) are your _promise_ to git that\neverything that is reachable from them are supposed to be\navailable in your repository.  If you remove specific commits by\nhand without adjusting the branch ref, you are breaking that\npromise and git-fsck will notice it as a repository breakage.\n\nIf you do not need a branch and everything reachable only from\nthat branch, you can remove that branch (with \"git branch -D\"),\nand run git-gc, which internally does the same reachability\nanalysis as git-fsck does and gets rid of objects that are no\nlonger necessary.\n"},{"id":"49286","messageId":"20070801074237.GA14790@raptus.dandreoli.com","threadId":"9335","inReplyTo":"7vhcnjbtpt.fsf@assigned-by-dhcp.cox.net","subject":"Re: dangling blob which is not dangling at all","fromName":"Domenico Andreoli","fromEmail":"cavokz@gmail.com","sentAt":"2007-08-01T07:42:37Z","receivedAt":"2007-08-01T07:42:37Z","isPatch":false,"sender":{"key":"cavokz@gmail.com","avatar":null},"body":"On Wed, Aug 01, 2007 at 12:27:10AM -0700, Junio C Hamano wrote:\n> Domenico Andreoli <cavokz@gmail.com> writes:\n> \n> > This fixed things and also warned about two heads referring to pruned\n> > commits, which may be those two commits I removed by hand (I hope).\n> \n> Exactly.\n> \n> All refs under .git/refs (the special case of this includes the\n> branch heads in .git/refs/heads) are your _promise_ to git that\n> everything that is reachable from them are supposed to be\n> available in your repository.  If you remove specific commits by\n> hand without adjusting the branch ref, you are breaking that\n> promise and git-fsck will notice it as a repository breakage.\n\nIf I move any ref by hand (not that I pass the day doing this..), I\nunderstand that some commits may suddenly result as unreachable. But\nthose commits I removed by hand were already unreachable so no refs\nshould have been referring them.\n\nWhat is this reflog thing and why is required?\n\nDomenico\n\n-----[ Domenico Andreoli, aka cavok\n --[ http://www.dandreoli.com/gpgkey.asc\n   ---[ 3A0F 2F80 F79C 678A 8936  4FEE 0677 9033 A20E BC50\n"},{"id":"49288","messageId":"46B045D3.4070208@midwinter.com","threadId":"9335","inReplyTo":"20070801074237.GA14790@raptus.dandreoli.com","subject":"Re: dangling blob which is not dangling at all","fromName":"Steven Grimm","fromEmail":"koreth@midwinter.com","sentAt":"2007-08-01T08:35:31Z","receivedAt":"2007-08-01T08:35:31Z","isPatch":false,"sender":{"key":"koreth@midwinter.com","avatar":"https://gravatar.com/avatar/71b4d2e8b62f168bdc9e9205341159e3567003b4f9e2127c617c5fa0a1f5bad2?d=mp&s=160"},"body":"Domenico Andreoli wrote:\n> What is this reflog thing and why is required?\n>   \n\nIt is a log of where each ref pointed at any given time. Or rather, a \nlog of changes to refs, with timestamps. It is not *required* per se \n(you can turn it off and almost all of git will continue to work as \nbefore) but it's handy in that you can say stuff like\n\ngit checkout -b newbranch master@\"{4 days ago}\"\n\nand git will give you a new branch pointing at the rev that master \npointed to 4 days ago, even if it's a rev that is no longer reachable \nfrom any of the existing heads (e.g., because you did a \"git rebase\" and \nthe rev in question was replaced by a new one.) Obviously as soon as you \ndo a \"git gc\" you will lose the ability to go back to unreachable revs \nusing the reflog.\n\nI primarily use the reflog to undo rebase operations. Not that I need to \ndo that very often, but it's occasionally handy, e.g., if there was a \nconflict and I made a mistake while resolving it.\n\n-Steve\n"},{"id":"49293","messageId":"46B04EB7.80006@dawes.za.net","threadId":"9335","inReplyTo":"46B045D3.4070208@midwinter.com","subject":"Re: dangling blob which is not dangling at all","fromName":"Rogan Dawes","fromEmail":"lists@dawes.za.net","sentAt":"2007-08-01T09:13:27Z","receivedAt":"2007-08-01T09:13:27Z","isPatch":false,"sender":{"key":"lists@dawes.za.net","avatar":null},"body":"Steven Grimm wrote:\n> Domenico Andreoli wrote:\n>> What is this reflog thing and why is required?\n>>   \n> \n> It is a log of where each ref pointed at any given time. Or rather, a \n> log of changes to refs, with timestamps. It is not *required* per se \n> (you can turn it off and almost all of git will continue to work as \n> before) but it's handy in that you can say stuff like\n> \n> git checkout -b newbranch master@\"{4 days ago}\"\n> \n> and git will give you a new branch pointing at the rev that master \n> pointed to 4 days ago, even if it's a rev that is no longer reachable \n> from any of the existing heads (e.g., because you did a \"git rebase\" and \n> the rev in question was replaced by a new one.) Obviously as soon as you \n> do a \"git gc\" you will lose the ability to go back to unreachable revs \n> using the reflog.\n> \n\nNot strictly true. \"git gc\" does take the reflogs into account when \ndetermining reachability, but it also prunes the reflogs periodically to \nprevent them from growing without bound (and preventing pruning of \notherwise unreachable objects).\n\n From the git-gc manpage:\n\nCONFIGURATION\n  The optional configuration variable gc.reflogExpire can be set to\n  indicate how long historical entries within each branch's reflog should\n  remain available in this repository. The setting is expressed as a\n  length of time, for example 90 days or 3 months. It defaults to 90\n  days.\n\nRegards,\n\nRogan\n"},{"id":"49311","messageId":"20070801142139.GA16607@raptus.dandreoli.com","threadId":"9335","inReplyTo":"46B04EB7.80006@dawes.za.net","subject":"Re: dangling blob which is not dangling at all","fromName":"Domenico Andreoli","fromEmail":"cavokz@gmail.com","sentAt":"2007-08-01T14:21:39Z","receivedAt":"2007-08-01T14:21:39Z","isPatch":false,"sender":{"key":"cavokz@gmail.com","avatar":null},"body":"On Wed, Aug 01, 2007 at 11:13:27AM +0200, Rogan Dawes wrote:\n> Steven Grimm wrote:\n>> Domenico Andreoli wrote:\n>>> What is this reflog thing and why is required?\n>>>   \n>> It is a log of where each ref pointed at any given time. Or rather, a log \n>> of changes to refs, with timestamps. It is not *required* per se (you can \n>> turn it off and almost all of git will continue to work as before) but \n>> it's handy in that you can say stuff like\n>> git checkout -b newbranch master@\"{4 days ago}\"\n>> and git will give you a new branch pointing at the rev that master pointed \n>> to 4 days ago, even if it's a rev that is no longer reachable from any of \n>> the existing heads (e.g., because you did a \"git rebase\" and the rev in \n>> question was replaced by a new one.) Obviously as soon as you do a \"git \n>> gc\" you will lose the ability to go back to unreachable revs using the \n>> reflog.\n>\n> Not strictly true. \"git gc\" does take the reflogs into account when \n> determining reachability, but it also prunes the reflogs periodically to \n> prevent them from growing without bound (and preventing pruning of \n> otherwise unreachable objects).\n\nso, besides playing with head refs by hand and forcing pushing to\n\"not strict subset\" heads, having dangling commits may be physiologic?\n\nand the only way to leak commits is from heads? on the countary, has\none a severely broken repository?\n\nmany thanks,\nDomenico\n\n-----[ Domenico Andreoli, aka cavok\n --[ http://www.dandreoli.com/gpgkey.asc\n   ---[ 3A0F 2F80 F79C 678A 8936  4FEE 0677 9033 A20E BC50\n"}]}