{"thread":{"id":"26774","subject":"Git fails to detect subcommand when hook is symlinked to a builtin","startedAt":"2011-03-18T15:14:15Z","lastAt":"2011-03-20T09:09:37Z","messageCount":6,"participants":["Todd Zullinger","Junio C Hamano","Jonathan Nieder"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"163647","messageId":"20110318151415.GC26236@inocybe.localdomain","threadId":"26774","inReplyTo":null,"subject":"Git fails to detect subcommand when hook is symlinked to a builtin","fromName":"Todd Zullinger","fromEmail":"tmz@pobox.com","sentAt":"2011-03-18T15:14:15Z","receivedAt":"2011-03-18T15:14:15Z","isPatch":false,"sender":{"key":"tmz@pobox.com","avatar":"https://avatars.githubusercontent.com/u/806319?v=4"},"body":"I'm not sure if this is a bug or more of a \"don't do that\" sort of\nthing.  At fedorahosted.org, the git repositories are mounted on a\nfilesystem with noexec.  As such, we have all hooks symlinked\nelsewhere.  For the post-update hook we used to link directly to\ngit-update-server-info.\n\nThis worked until we upgraded the system to git-1.7.4.1 recently.  A\ntrace may help illustrate:\n\nWith hooks/post-update as a symlink to\n/usr/bin/git-update-server-info:\n\ntrace: run_command: 'hooks/post-update' 'refs/heads/master'\ntrace: run_command: 'gc' '--auto' '--quiet'\nremote: trace: exec: 'git-refs/heads/master'\nremote: trace: run_command: 'git-refs/heads/master'\nremote: git: 'refs/heads/master' is not a git command. See 'git --help'.\n\nWith hooks/post-update as a symlink to\n/usr/share/git-core/templates/hooks/post-update.sample:\n\ntrace: run_command: 'hooks/post-update' 'refs/heads/master'\nremote: setup: git_dir: .\nremote: setup: worktree: (null)\nremote: setup: cwd: /home/fedora/tmz/tmp/iwhd.git\nremote: setup: prefix: (null)\nremote: trace: built-in: git 'update-server-info'\n\nIs there any reasonable way to handle this case?  Perhaps if the\nsymlink were dereferenced (if no subcommand were found) and then\nre-checked for a subcommand?  I admit that I did not delve too deeply\ninto the code, but from the little I did I wasn't sure that any\nchanges here wouldn't lead to worse troubles.\n\n-- \nTodd        OpenPGP -> KeyID: 0xBEAF0CE3 | URL: www.pobox.com/~tmz/pgp\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nEveryone needs to believe in something. I believe I'll have another\nbeer.\n\n"},{"id":"163695","messageId":"7vhbb0rkv4.fsf@alter.siamese.dyndns.org","threadId":"26774","inReplyTo":"20110318151415.GC26236@inocybe.localdomain","subject":"Re: Git fails to detect subcommand when hook is symlinked to a builtin","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-03-19T00:53:51Z","receivedAt":"2011-03-19T00:53:51Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Todd Zullinger <tmz@pobox.com> writes:\n\n> I'm not sure if this is a bug or more of a \"don't do that\" sort of\n> thing.  At fedorahosted.org, the git repositories are mounted on a\n> filesystem with noexec.  As such, we have all hooks symlinked\n> elsewhere.  For the post-update hook we used to link directly to\n> git-update-server-info.\n>\n> This worked until we upgraded the system to git-1.7.4.1 recently.\n\nI have a suspicion that we may end up saying \"don't do that\", but let's\nponder a bit with some technical background first.  The \"git\" wrapper and\nbuiltin commands are all the same binary, and as a consequence, their\nmain() function needs to decide what to do based on argv[0].  If argv[0]\nis \"git\", we know argv[1] is the name of the subcommand, and if argv[0] is\n\"git-foo\", it might be the internal call from the \"git\" wrapper that was\ninvoked with argv[] = { \"git\", \"foo\", ... }, but we don't expect that\nargv[0] to be things like \"post-update\".\n\nBut it is curious why the resulting behaviour changed recently.  The\nsymptom hints that the link target (git-update-server-info in your case)\nused to be given as argv[0] (which still wouldn't have been kosher---you\nare not supposed to use dashed form since 1.5.4 or so without adding\n$GIT_EXEC_PATH at the beginning of your $PATH, and that is why I said the\nfirst sentence in this reply), but we recently changed something and now\nwe are getting \"hooks/post-update\" in argv[0].\n\nI suspect the recent change to run hooks via run_command() interface has\nsomething to do with it.  From what version did you update to 1.7.4.1?\n"},{"id":"163696","messageId":"20110319011445.GL26236@inocybe.localdomain","threadId":"26774","inReplyTo":"7vhbb0rkv4.fsf@alter.siamese.dyndns.org","subject":"Re: Git fails to detect subcommand when hook is symlinked to a builtin","fromName":"Todd Zullinger","fromEmail":"tmz@pobox.com","sentAt":"2011-03-19T01:14:45Z","receivedAt":"2011-03-19T01:14:45Z","isPatch":false,"sender":{"key":"tmz@pobox.com","avatar":"https://avatars.githubusercontent.com/u/806319?v=4"},"body":"Junio C Hamano wrote:\n> I have a suspicion that we may end up saying \"don't do that\", but\n> let's ponder a bit with some technical background first.  The \"git\"\n> wrapper and builtin commands are all the same binary, and as a\n> consequence, their main() function needs to decide what to do based\n> on argv[0].  If argv[0] is \"git\", we know argv[1] is the name of the\n> subcommand, and if argv[0] is \"git-foo\", it might be the internal\n> call from the \"git\" wrapper that was invoked with argv[] = { \"git\",\n> \"foo\", ... }, but we don't expect that argv[0] to be things like\n> \"post-update\".\n\nI can certainly understand that. :)\n\n> But it is curious why the resulting behaviour changed recently.  The\n> symptom hints that the link target (git-update-server-info in your\n> case) used to be given as argv[0] (which still wouldn't have been\n> kosher---you are not supposed to use dashed form since 1.5.4 or so\n> without adding $GIT_EXEC_PATH at the beginning of your $PATH, and\n> that is why I said the first sentence in this reply), but we\n> recently changed something and now we are getting\n> \"hooks/post-update\" in argv[0].\n>\n> I suspect the recent change to run hooks via run_command() interface\n> has something to do with it.  From what version did you update to\n> 1.7.4.1?\n\nI should have mentioned it, but I failed to do so.  Sorry about that.\n\nThis was moving from 1.5.5.6 to 1.7.4.1. The packages for EPEL (extra\nstuff for RHEL/CentOS) lagged behind for quite some time.  The\nfedorahosted.org system was using 1.5.5.6 for a long time with the\nsymlinked post-update hook in place.  But it's not necessarily\nanything that changed recently in git.  It could have been changes all\nthe way back in 1.6.0, which seems like an eternity in git time.\n\nWe already fixed up the repositories on fedorahosted for this, but I\nfigured I should ask, in case this change was not intended and might\ncatch other folks doing git hosting.\n\n(The only other minor change that caught us was that some of the repos\ndid not have core.bare = true and pushes to these oddly configured\nrepositories failed.  Clearly, that was a misconfiguration from the\ntime the repos were setup.  Otherwise, for moving from 1.5.5.6 to\n1.7.4.1, things went quite smoothly.  That's thanks in no small part\nto the great attention to detail you and the other folks on this list\nhave.  Thank you!)\n\n-- \nTodd        OpenPGP -> KeyID: 0xBEAF0CE3 | URL: www.pobox.com/~tmz/pgp\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThe United States is a nation of laws, badly written and randomly\nenforced.\n    -- Frank Zappa\n\n"},{"id":"163773","messageId":"7voc56rj9f.fsf@alter.siamese.dyndns.org","threadId":"26774","inReplyTo":"20110319011445.GL26236@inocybe.localdomain","subject":"Re: Git fails to detect subcommand when hook is symlinked to a builtin","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-03-19T19:40:44Z","receivedAt":"2011-03-19T19:40:44Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Todd Zullinger <tmz@pobox.com> writes:\n\n>> I suspect the recent change to run hooks via run_command() interface\n>> has something to do with it.  From what version did you update to\n>> 1.7.4.1?\n>\n> I should have mentioned it, but I failed to do so.  Sorry about that.\n>\n> This was moving from 1.5.5.6 to 1.7.4.1.\n\nOk, that explains it.  update-server-info wasn't a built-in, so didn't\nhave to look at its name to decide what to do.  It didn't have to spawn\nother git commands from GIT_EXEC_PATH so running the command directly\nwithout setting the environment variable happened to work.\n\nBut such a usage (this doesn't have anything to do with the symlinking)\nwas deprecated way before 1.5.4 [*1*], so the answer is still \"don't do\nthat\" ;-)\n\nThanks for a clarification.\n\n\n[Reference]\n\n*1* http://thread.gmane.org/gmane.comp.version-control.git/93511\n"},{"id":"163805","messageId":"20110320082020.GA12663@elie","threadId":"26774","inReplyTo":"7voc56rj9f.fsf@alter.siamese.dyndns.org","subject":"Re: Git fails to detect subcommand when hook is symlinked to a builtin","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2011-03-20T08:20:20Z","receivedAt":"2011-03-20T08:20:20Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Junio C Hamano wrote:\n\n> Ok, that explains it.  update-server-info wasn't a built-in, so didn't\n> have to look at its name to decide what to do.  It didn't have to spawn\n> other git commands from GIT_EXEC_PATH so running the command directly\n> without setting the environment variable happened to work.\n\nNice detective work.\n\n> But such a usage (this doesn't have anything to do with the symlinking)\n> was deprecated way before 1.5.4 [*1*], so the answer is still \"don't do\n> that\" ;-)\n[...]\n> *1* http://thread.gmane.org/gmane.comp.version-control.git/93511\n\nAfter rereading some of that thread (oops), I feel a small clarification\nis in order.  Yes, the dashed named git-update-server-info is not the\nname that that command would preferred to be called by, but if I\nunderstand correctly, this is not what you are talking about having\nbeing deprecated and removed.  Instead, the rule is:\n\n If you set your $PATH to include $(git --exec-path), then you may still\n run traditional git-<command>s using that dashed name.  Otherwise, you\n may be lucky and find it working (which is probably a bug :)) but\n please, just say no.[1]\n\nRationale: in that thread, the change to $PATH was agreed on as a\nlong-term workaround for preserving scripts and muscle memory.\n\nRegards,\nJonathan\n\n[1] In practice: the git wrapper adds GIT_EXEC_PATH to the $PATH and\ntraditional commands rely on finding it there.  For example, when\ngit-<command> is a shell script, it will tend to begin by reading in\nsome useful functions by running \". git-sh-setup\", which relies on\ngit-sh-setup lying on the $PATH.\n"},{"id":"163810","messageId":"20110320090937.GA13167@elie","threadId":"26774","inReplyTo":"20110320082020.GA12663@elie","subject":"Re: Git fails to detect subcommand when hook is symlinked to a builtin","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2011-03-20T09:09:37Z","receivedAt":"2011-03-20T09:09:37Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Jonathan Nieder wrote:\n\n> Instead, the rule is:\n\nSorry, that came out a muddle.  Teemu Likonen explains the rule[1]\nbetter.  And Linus explains the rationale[2].  The main reason I found\nthis interesting enough to chime in is that I was considering\nproposing changing the beginning of git scripts to\n\n . \"$(git --exec-path)/git-sh-setup\"\n\nto set a good example, which would be a regression in git's ability\nto complain when used in a fragile way.\n\nSo, Todd: thanks for a very useful reminder.\n\n[1] http://thread.gmane.org/gmane.comp.version-control.git/94378\n[2] http://thread.gmane.org/gmane.comp.version-control.git/93825\n"}]}