{"action":"created","issue":{"url":"https://api.github.com/repos/libgit2/libgit2/issues/3004","labels_url":"https://api.github.com/repos/libgit2/libgit2/issues/3004/labels{/name}","comments_url":"https://api.github.com/repos/libgit2/libgit2/issues/3004/comments","events_url":"https://api.github.com/repos/libgit2/libgit2/issues/3004/events","html_url":"https://github.com/libgit2/libgit2/pull/3004","id":63287615,"number":3004,"title":"Adding initial support for hooks","user":{"login":"maolivo","id":10779059,"avatar_url":"https://avatars.githubusercontent.com/u/10779059?v=3","gravatar_id":"","url":"https://api.github.com/users/maolivo","html_url":"https://github.com/maolivo","followers_url":"https://api.github.com/users/maolivo/followers","following_url":"https://api.github.com/users/maolivo/following{/other_user}","gists_url":"https://api.github.com/users/maolivo/gists{/gist_id}","starred_url":"https://api.github.com/users/maolivo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/maolivo/subscriptions","organizations_url":"https://api.github.com/users/maolivo/orgs","repos_url":"https://api.github.com/users/maolivo/repos","events_url":"https://api.github.com/users/maolivo/events{/privacy}","received_events_url":"https://api.github.com/users/maolivo/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":17,"created_at":"2015-03-20T19:26:58Z","updated_at":"2015-06-01T20:34:11Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/libgit2/libgit2/pulls/3004","html_url":"https://github.com/libgit2/libgit2/pull/3004","diff_url":"https://github.com/libgit2/libgit2/pull/3004.diff","patch_url":"https://github.com/libgit2/libgit2/pull/3004.patch"},"body":"@ethomson and I have been discussing adding hooks support to LibGit2 for the last month or two. My ideas for the design of this came from what has been laid out in the contributing guide:\r\n\r\n- Add hooks API to enumerate and manage hooks (not run them at this point)\r\n  - Enumeration of available hooks\r\n  - Lookup API to see which hooks have a script and get the script\r\n  - Read/write API to load a hook script and write a hook script\r\n  - Eventually, callback API to invoke a hook callback when libgit2 executes the action in question\r\n\r\nThe purpose of this pull request is to tackle the first two bullet points; enumerating all available hooks and the ability to get the script for a given hook.\r\n\r\nBefore I go into my reasoning for the proposed design, let me cover some issues that influenced it.\r\n- The simplest question probably had the biggest influence; \"how do get a specific hook?\" once I have retrieved all the hooks present in a repository.\r\n- Different platforms distributions of git support a different number of hooks (Git for Windows only supports 9 of the 17 hooks that exist in Git). Because of the variable amount of hooks that could be supported on any platform, do we allow a Windows user to query for a hook that doesn't exist in Git for Windows?\r\n- Since a command can have multiple hooks associated with it (commit has 4; pre-commit, prepare-commit-msg, commit-msg, post-commit), it will need to query for each of these hook's availability while it is performing its actions.\r\n\r\nBased on the above issues, here is my proposed design:\r\n- A single API method to query for a __*git_repository_hooks*__ object which contains\r\n  - The full directory path to the hooks directory\r\n  - An array of all supported (known) hooks\r\n- Each index in the array contains a __*git_hook*__ object which contains:\r\n  - Whether the hook exists for the repo\r\n  - The file name of the hook\r\n- The array can be queried for a specific hook by using an enum value which is the index location for that specific hook. These enums all start with __*GIT_HOOK_INDEX*__.\r\n- Since each platform supports a variable amount of all hooks, we will not filter our returned hooks based on the platform. We will query for every known hook in a repository and return all that are found.\r\n- Since some commands need to use multiple hooks in their process, it doesn't make sense to hit disk multiple times to re-query for each individual hook. Instead, we can query once, get all available hooks, and the caller can then use that hooks object for the rest of its life-cycle.\r\n\r\nA few things I also wanted to call out in advance for this pull request:\r\n- With this initial design, the onus is on the caller to query for the hooks and then execute them appropriately\r\n- I am currently not including any information about how many arguments a given hook is expecting as this is a non-trivial problem. Some hooks take no arguments, some take a guaranteed number, some take a specific variable number, and some take a indeterminate number. Although we can't guarantee how many arguments a script should get, we do know exactly what each argument will be when it is passed in. I think this will be heavily influenced by how the callback API is tackled and vice-versa. For more information about this specifically: https://www.kernel.org/pub/software/scm/git/docs/githooks.html\r\n\r\nPlease let me know what you think of the design and what changes you think should occur."},"comment":{"url":"https://api.github.com/repos/libgit2/libgit2/issues/comments/107699059","html_url":"https://github.com/libgit2/libgit2/pull/3004#issuecomment-107699059","issue_url":"https://api.github.com/repos/libgit2/libgit2/issues/3004","id":107699059,"user":{"login":"carlosmn","id":335443,"avatar_url":"https://avatars.githubusercontent.com/u/335443?v=3","gravatar_id":"","url":"https://api.github.com/users/carlosmn","html_url":"https://github.com/carlosmn","followers_url":"https://api.github.com/users/carlosmn/followers","following_url":"https://api.github.com/users/carlosmn/following{/other_user}","gists_url":"https://api.github.com/users/carlosmn/gists{/gist_id}","starred_url":"https://api.github.com/users/carlosmn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/carlosmn/subscriptions","organizations_url":"https://api.github.com/users/carlosmn/orgs","repos_url":"https://api.github.com/users/carlosmn/repos","events_url":"https://api.github.com/users/carlosmn/events{/privacy}","received_events_url":"https://api.github.com/users/carlosmn/received_events","type":"User","site_admin":false},"created_at":"2015-06-01T20:34:11Z","updated_at":"2015-06-01T20:34:11Z","body":"This isn't about implementing the pre-push hook. We are solving the same problem, but copying 1-to-1 the way git interacts with its environment often does not make sense.\r\n\r\nThis is also not about libgit2's internals. I don't see why we would want to swap `src` and `dst`. Maybe the names could be clearer, but swapping them makes no sense to me."}}