{"thread":{"id":"29412","subject":"git clone, hardlinks and multiple users?","startedAt":"2012-01-20T17:31:59Z","lastAt":"2012-01-23T17:55:37Z","messageCount":3,"participants":["Marc Herbert","Neal Kreitzinger"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"182880","messageId":"jfc8eh$ck5$1@dough.gmane.org","threadId":"29412","inReplyTo":null,"subject":"git clone, hardlinks and multiple users?","fromName":"Marc Herbert","fromEmail":"marc.herbert+news@gmail.com","sentAt":"2012-01-20T17:31:59Z","receivedAt":"2012-01-20T17:31:59Z","isPatch":false,"sender":{"key":"marc.herbert+news@gmail.com","avatar":null},"body":"Hi,\n\n   \"git clone\" is using hardlinks by default, even when cloning from a \ndifferent user. In such a case the clone ends up with a number of files \nowned by someone else.\n\nSince only immutable objects are cloned this seems to work fine. However \nI would like to know if this \"multiple users\" case works by chance or by \nspecification.\n\nIn other words, is there a guarantee that no later version of git or no \nobscure option I haven't used yet will ever try to touch a hardlink in \nany way like for instance: trying update some metadata timestamp or, \noverwrite it with the same value by lack of optimization, or any other \nkind of side-effect that would obviously fail.\n\nThanks in advance!\n\nMarc\n"},{"id":"182913","messageId":"4F1B420D.7050800@gmail.com","threadId":"29412","inReplyTo":"jfc8eh$ck5$1@dough.gmane.org","subject":"Re: git clone, hardlinks and multiple users?","fromName":"Neal Kreitzinger","fromEmail":"nkreitzinger@gmail.com","sentAt":"2012-01-21T22:54:05Z","receivedAt":"2012-01-21T22:54:05Z","isPatch":false,"sender":{"key":"nkreitzinger@gmail.com","avatar":null},"body":"On 1/20/2012 11:31 AM, Marc Herbert wrote:\n> Hi,\n>\n> \"git clone\" is using hardlinks by default, even when cloning from a\n> different user. In such a case the clone ends up with a number of\n> files owned by someone else.\n>\n(I assume your using linux.) It sounds like you specified a url syntax\nof /path/to/repo.git in your git-clone which tells git to use hardlinks.\n  If you want your own copies then specify file:///path/to/repo.git in\ngit-clone (see git-clone manpage section \"GIT URLS\":\nhttp://schacon.github.com/git/git-clone.html).\n\n> Since only immutable objects are cloned this seems to work fine.\n> However I would like to know if this \"multiple users\" case works by\n> chance or by specification.\n>\n(I'm not an expert on hardlinks, linux metadata, or git, and haven't\nused hardlinks at all with linux or git yet, but do have some experience\nwith git and permissions.)  I think if you plan your permissions to be\nbased on a primary group then it will \"just work\".  If its not as simple\nas a single primary group, then read on for my non-expert conversational\ninput, or at least skim thru for pointers to the reliable manpage\nreferences...\n\nIt sounds like part of your question may actually be a hardlink\nquestion so perhaps this info on hardlinks is useful:\nhttp://linfo.org/hard_link.html to you. In regards to git, it does not\ntrack metadata.  However, it will track\n\"permissions\" if you tell it to, but even then it only tracks the\nexecutable bit to determine if its stored in the git repo as executable\nor non-executable.  If you are \"changing\" the metadata because you\nmodified the file contents (or executable bit) then\nyou are creating a new object (in git) and not modifying the original\nhardlinked object (in git or linux) or its metadata (in linux).  I\nassume the working-tree (ie., WORKTREE/ of WORKTREE/.git repo) of the\nclone is indeed a full copy of the files via git-checkout because the\nmanpage only claims to use hardlinks for the object store (ie.\n.git/objects/) to save diskspace on the clone of the object store, not\nthe checkout of the worktree.  Worktree objects only get written\nto the object store if you stage them to the index (git-add).  Then they\nare stored in .git/objects/ according to the sha-1 of their\ncontents.  Therefore, if your worktree copy has a different owner and\nyou don't modify the contents or executable bit then you can't possibly\nstage it because git does not detect a difference in content or\nexecutable bit.  On the other hand, if you change the contents or the\nexecutable bit then git will consider that a change and update the\nobject store, but it will be a new object and not the object\nrepresenting the previous version you hardlinked to when you cloned.  If\nthat new object is then in turn pushed to the origin repo and someone\nelse clones it using hardlinks then they may very well not\nbe able to access that object if its owner:group excludes them.  More\nlikely, if someone pushes an object with bad permissions then others\nwill get push errors because git stores objects in subdirs named after\nthe first two chars of the sha-1 which means other objects in that\nsubdir will also be inaccessible.  If you change permissions in regard\nto executable bit on your files without editing contents then I don't\nknow if git will make a new copy or modify the original inode because\nI'm not sure if the executable bit permissions is represented in the\nsha-1 contents or not.  In the git-init manpage there are options for\npermissions/sharing under the --shared option (not to be confused with\nthe --shared option of git-clone which it totally different).  The\ngit-clone equivalent appears to be \"git-clone --config\ncore.sharedRepository=<your-value>\".  Maybe these core.sharedRepository\nsettings in git are smart enough to handle the hardlink shared inode\nmetadata confusion.\n\n> In other words, is there a guarantee that no later version of git or\n>  no obscure option I haven't used yet will ever try to touch a\n> hardlink in any way like for instance: trying update some metadata\n> timestamp or, overwrite it with the same value by lack of\n> optimization, or any other kind of side-effect that would obviously\n> fail.\n>\nHowever, if you cd to .git/objects/ and use chmod to change the\npermission directly then I think it would change the permissions on the\ninodes your origin is storing as loose objects.  I'm not sure what it\nwould do for packed objects. There are clone options like --shared and \n--reference that have special notes on the manpage explaining how you \ncould break things if you don't know what you're doing (that would \ninclude hardlinks but is not exclusive to hardlinks).\n\nHope this helps in some way.  Perhaps someone better informed will \nprovide a more accurate and/or clear answer.  Let me know what\nyou find out because I too will have to become more concerned about\ndiskspace and clone optimization in the very near future.\n\nv/r,\nneal\n"},{"id":"182974","messageId":"jfk6up$3dj$1@dough.gmane.org","threadId":"29412","inReplyTo":"jfc8eh$ck5$1@dough.gmane.org","subject":"Re: git clone, hardlinks and multiple users?","fromName":"Marc Herbert","fromEmail":"marc.herbert+news@gmail.com","sentAt":"2012-01-23T17:55:37Z","receivedAt":"2012-01-23T17:55:37Z","isPatch":false,"sender":{"key":"marc.herbert+news@gmail.com","avatar":null},"body":"On 20/01/2012 17:31, Marc Herbert wrote:\n> \"git clone\" is using hardlinks by default, even when cloning from a\n> different user. In such a case the clone ends up with a number of files\n> owned by someone else.\n>\n> Since only immutable objects are cloned this seems to work fine. However\n> I would like to know if this \"multiple users\" case works by chance or by\n> specification.\n\nSorry I meant: \"since only immutable objects are HARDLINKED this seems \nto work fine\".\n\nA few other clarifications following Neal's long answer:\n\n- Yes we are using Linux. But the question is about any filesystem \nsupporting hardlinks and user permissions.\n\n- My question is only about hardlinks in .git/objects/. Whatever happens \nin the checkout is irrelevant.\n\n- I know how to clone with no hardlink and completely avoid the whole \nissue. Unfortunately people have this strange habit of using the \nsimplest/default option, and it does hardlinks.\n\nI guess my rephrased question is: while there is no obvious reason for \ngit to attempt to touch files in .git/objects/, is there a promise that \nthis will never, ever happen? Because it would fail in a multi-users config.\n\nThe \"core.sharedRepository\" option is good example. When set to a new \nvalue will it ever try to fix existing objects? That would fail.\n"}]}