{"thread":{"id":"3315","subject":"git-cvsserver & push/commit atomically","startedAt":"2006-02-12T23:50:47Z","lastAt":"2006-02-13T02:25:00Z","messageCount":3,"participants":["Martin Langhoff","Johannes Schindelin","Randal L. Schwartz"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"16002","messageId":"46a038f90602121550v4f487edfs788885a78c1b167@mail.gmail.com","threadId":"3315","inReplyTo":null,"subject":"git-cvsserver & push/commit atomically","fromName":"Martin Langhoff","fromEmail":"martin.langhoff@gmail.com","sentAt":"2006-02-12T23:50:47Z","receivedAt":"2006-02-12T23:50:47Z","isPatch":false,"sender":{"key":"martin.langhoff@gmail.com","avatar":"https://gravatar.com/avatar/1e3f311b6c4c15836501901ca58f8c0b0667246488084ba524d8bc9867e22fd9?d=mp&s=160"},"body":"I am trying to figure out a safe way to lock the git repo to prevent\nclients pushing to it while someone else (via git-cvsserver.pl) is\nmanipulating it. Push and commit are *mostly* transactional it seems,\nbut I'm not 100% clear on how the head update gets updated safely.\n\nAhhhh. Hmmm. Reading git-receive-pack.c update(), it seems that we\nhave to mimic that behaviour in Perl. The semantics are a bit weird\nfor me -- not used to safe C open()s. From what I read, it looks like\nit\n\n - precondition: all the relevant objects are already in the repo\n - reads old sha1\n - creates repo.git/refs/<headname>.lock file with new sha1\n - compares old and current head\n - runs update hooks\n - renames repo.git/refs/<headname>.lock into repo.git/refs/<headname>\n\nSo it is mostly race-safe, except for the window while we are running\nupdate hooks. Only a misbehaving implementation that doesn't fail on\nthe creation of repo.git/refs/<headname>.lock  would affect us there,\nthough. Would locking repo.git/refs/<headname> make sense?\n\ngit-cvsserver commits are likely to be slow (not only likely, they\n_are_ slow right now), so we need a way to block other clients for a\nrelatively long time.\n\ncheers,\n\n\nmartin\n"},{"id":"16006","messageId":"Pine.LNX.4.63.0602130110590.21465@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"3315","inReplyTo":"46a038f90602121550v4f487edfs788885a78c1b167@mail.gmail.com","subject":"Re: git-cvsserver & push/commit atomically","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2006-02-13T00:17:23Z","receivedAt":"2006-02-13T00:17:23Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 13 Feb 2006, Martin Langhoff wrote:\n\n>  - precondition: all the relevant objects are already in the repo\n>  - reads old sha1\n>  - creates repo.git/refs/<headname>.lock file with new sha1\n>  - compares old and current head\n>  - runs update hooks\n>  - renames repo.git/refs/<headname>.lock into repo.git/refs/<headname>\n> \n> So it is mostly race-safe, except for the window while we are running\n> update hooks. Only a misbehaving implementation that doesn't fail on\n> the creation of repo.git/refs/<headname>.lock  would affect us there,\n> though. Would locking repo.git/refs/<headname> make sense?\n\nCorrect. The filesystem way to lock is to create a lock file and fail if \nit already exists. Since you are doing something akin to git-commit, I \nthink you *must* lock repo.git/refs/<headname>.\n\n> git-cvsserver commits are likely to be slow (not only likely, they\n> _are_ slow right now), so we need a way to block other clients for a\n> relatively long time.\n\nI don't think there is a way around that. Of course, you could write the \nobjects first without locking. But then you probably have loose objects in \nthe repository if the commit fails due to another commit in the meantime.\n\n<becomessweatyhands>\n\tBTW when are we going to see git-cvsserver?\n</becomessweatyhands>\n\nCiao,\nDscho\n"},{"id":"16012","messageId":"86wtg0j8qr.fsf@blue.stonehenge.com","threadId":"3315","inReplyTo":"Pine.LNX.4.63.0602130110590.21465@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: git-cvsserver & push/commit atomically","fromName":"Randal L. Schwartz","fromEmail":"merlyn@stonehenge.com","sentAt":"2006-02-13T02:25:00Z","receivedAt":"2006-02-13T02:25:00Z","isPatch":false,"sender":{"key":"merlyn@stonehenge.com","avatar":"https://gravatar.com/avatar/dc528d210743ff0333e6213f9ee7b33b23f1b7bc1f3c5a8c2d819074ecd7ab19?d=mp&s=160"},"body":">>>>> \"Johannes\" == Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\nJohannes> Correct. The filesystem way to lock is to create a lock file and\nJohannes> fail if it already exists.\n\nUnless NFS has been fixed, that's not an atomic operation over NFS.  Might not\nmatter here, but important to note if this is your first time seeing this lock\nstrategy.\n\n-- \nRandal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095\n<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>\nPerl/Unix/security consulting, Technical writing, Comedy, etc. etc.\nSee PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!\n"}]}