{"action":"created","comment":{"url":"https://api.github.com/repos/metomi/fcm/pulls/comments/35522660","id":35522660,"diff_hunk":"@@ -0,0 +1,571 @@\n+#-------------------------------------------------------------------------------\n+# (C) British Crown Copyright 2006-14 Met Office.\n+#\n+# This file is part of FCM, tools for managing and building source code.\n+#\n+# FCM is free software: you can redistribute it and/or modify\n+# it under the terms of the GNU General Public License as published by\n+# the Free Software Foundation, either version 3 of the License, or\n+# (at your option) any later version.\n+#\n+# FCM is distributed in the hope that it will be useful,\n+# but WITHOUT ANY WARRANTY; without even the implied warranty of\n+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+# GNU General Public License for more details.\n+#\n+# You should have received a copy of the GNU General Public License\n+# along with FCM. If not, see <http://www.gnu.org/licenses/>.\n+#-------------------------------------------------------------------------------\n+\n+use strict;\n+use warnings;\n+\n+package FCM::Admin::Commit;\n+\n+use Exporter qw{import};\n+our @EXPORT_OK = qw{\n+    post_commit_notify_who\n+    pre_commit_perm\n+};\n+\n+use File::Spec::Functions qw{catfile};\n+use File::Temp;\n+use Memoize qw{memoize};\n+\n+use FCM::Admin::Config;\n+use FCM::Admin::System qw{get_users verify_users};\n+use FCM::Context::Locator;\n+use FCM::System::CM::SVN;\n+\n+my $COMMIT_CONF_BASE = 'commit.cfg';\n+my $UTIL = $FCM::Admin::Config::UTIL;\n+my $CM_SYS = FCM::System::CM::SVN->new({'util' => $UTIL});\n+my %WARN_FMT_OF = (\n+    'CONF' => \"\\tINVALID CONFIGURATION\\n\",\n+    'CONF_NS' => \"\\tBAD NAMESPACE: %s\\n\",\n+    'CONF_VALUE' => \"\\tBAD VALUE: %s\\n\",\n+    'OWNER' => \"\\tBAD CONF: owner[] undefined with %s=repository|project\\n\",\n+    'PERM' => \"PERMISSION DENIED: %s\\n\",\n+);\n+\n+# Implement functionalities for \"post-commit-notify-who\"\n+sub post_commit_notify_who {\n+    my ($repos, $rev, $txn) = @_;\n+\n+    my $commit_conf = _load_commit_conf($repos);\n+    if (!defined($commit_conf)) {\n+        return;\n+    }\n+\n+    # Named repository owners can modify any path.\n+    my $author = _get_author($repos, $rev, $txn);\n+    $CM_SYS->load_layout_config('file://' . $repos);\n+    my %names = (); # {$name1 => 1, $name2 => 1, ...}\n+    LINE:\n+    for my $line ($CM_SYS->stdout(qw{svnlook changed -r}, $rev, $repos)) {\n+        my $status = substr($line, 0, 1);\n+        my $path = substr($line, 4);\n+        my $layout = $CM_SYS->get_layout_common(\n+            $repos,\n+            ($status eq 'D' ? $rev - 1 : $rev),\n+            \"/$path\",\n+            $CM_SYS->IS_LOCAL,\n+        );\n+        my $project = $layout->get_project();\n+        my $branch = $layout->get_branch();\n+\n+        # Notify branch subscribers/owners\n+        if (    $commit_conf->get_notification_modes()->{'branch'}\n+            &&  $layout->is_branch()\n+            &&  defined($branch)\n+        ) {\n+            my $branch_path = join(q{/}, grep {$_} ($project, $branch));\n+            if (!exists($commit_conf->get_owners_of()->{\"$branch_path/\"})) {\n+                my $owner = $layout->is_shared()\n+                    ? _get_path_creator($repos, $rev, $project, $branch)\n+                    : $layout->get_branch_owner()\n+                    ;\n+                if ($owner) {\n+                    $commit_conf->get_owners_of()->{$branch_path} = [$owner];\n+                }\n+            }\n+            for my $user ($commit_conf->get_notifiables_of($branch_path)) {\n+                $names{$user} = 1;\n+            }\n+            next LINE;\n+        }\n+\n+        # Notify project subscribers/owners\n+        if (    $commit_conf->get_notification_modes()->{'project'}\n+            &&  defined($project)\n+        ) {\n+            for my $user ($commit_conf->get_notifiables_of(\"$project/\")) {\n+                $names{$user} = 1;\n+            }\n+            next LINE;\n+        }\n+\n+        # Notify repository subscribers/owners\n+        if ($commit_conf->get_notification_modes()->{'repository'}) {\n+            for my $user ($commit_conf->get_notifiables_of(q{})) {\n+                $names{$user} = 1;\n+            }\n+            next LINE;\n+        }\n+    }\n+\n+    # Don't notify author\n+    if (exists($names{$author})) {\n+        delete($names{$author});\n+    }\n+    # Return list of emails\n+    my @users = %names ? values(%{get_users(keys(%names))}) : ();\n+    return sort grep {$_} map {$_->get_email()} @users;\n+}\n+\n+# Implement functionalities for \"pre-commit-perm\"\n+sub pre_commit_perm {\n+    my ($repos, $txn) = @_;\n+\n+    my $commit_conf = _load_commit_conf($repos);\n+\n+    # Check permission:\n+    my $author = _get_author($repos, undef, $txn);\n+    $CM_SYS->load_layout_config('file://' . $repos);\n+    my %line_of_unknown_path;\n+    my @bads;\n+    LINE:\n+    for my $line ($CM_SYS->stdout(qw{svnlook changed -t}, $txn, $repos)) {\n+        my $status = substr($line, 0, 1);\n+        my $path = substr($line, 4);\n+        # Ensure values for changes in \"commit.cfg\" are valid\n+        if ($status ne 'D' && $path eq $COMMIT_CONF_BASE) {\n+            my @problems = _check_commit_conf($commit_conf, $repos, $txn);\n+            if (@problems) {\n+                push(@bads, [$line, @problems]);\n+            }\n+            next LINE;\n+        }\n+        # Allow addition of intermediate directories on creation of projects\n+        if ($status eq 'A') {\n+            while (my $unknown_path = each(%line_of_unknown_path)) {\n+                if (index($path, $unknown_path) == 0) {\n+                    delete($line_of_unknown_path{$unknown_path});\n+                }\n+            }\n+        }\n+        my $layout = $CM_SYS->get_layout_common(\n+            $repos, $txn, \"/$path\", $CM_SYS->IS_LOCAL);\n+        my $project = $layout->get_project();\n+        my $branch = $layout->get_branch();\n+        # Branch owner perm mode\n+        if (    $commit_conf->get_permission_modes()->{'branch'}\n+            &&  $layout->is_branch()\n+            &&  defined($branch)\n+        ) {\n+            my $branch_path = join(q{/}, grep {$_} ($project, $branch));\n+            if (!exists($commit_conf->get_owners_of()->{$branch_path})) {\n+                # Anyone can create a shared branch\n+                if (    $layout->is_shared()\n+                    &&  $status eq 'A'\n+                    &&  $path eq \"$branch_path/\"\n+                ) {\n+                    next LINE;\n+                }\n+                my $owner = $layout->is_shared()\n+                    ? _get_path_creator($repos, undef, $project, $branch)\n+                    : $layout->get_branch_owner()\n+                    ;\n+                if ($owner) {\n+                    $commit_conf->get_owners_of()->{$branch_path} = [$owner];\n+                }\n+            }\n+            # Create branch with user ID in branch name: can only be done by\n+            # author of the same user ID.\n+            # For all other changes, check permission as usual.\n+            if (    (       !$layout->is_shared()\n+                        &&  $status eq 'A'\n+                        &&  $path eq \"$branch_path/\"\n+                        &&  $author ne $layout->get_branch_owner()\n+                    )\n+                ||  !_perm_ok($commit_conf, $author, $project, $branch)\n+            ) {\n+                push(@bads, [$line]);\n+            }\n+            next LINE;\n+        }\n+        # Project owner can do anything to paths at or under the project\n+        if (    $commit_conf->get_permission_modes()->{'project'}\n+            &&  defined($project)\n+        ) {\n+            if (!_perm_ok($commit_conf, $author, $project)) {\n+                # An author who is not a project owner can add paths under the\n+                # project as part of a branch creation, etc.\n+                # \"$line_of_unknown_path{$path}\" may be deleted if it is a part\n+                # of a valid branch creation by an author who is not a project\n+                # owner.\n+                if ($status eq 'A' && !$branch) {\n+                    $line_of_unknown_path{$path} = $line;\n+                }\n+                # Permission denied for everything else under the project.\n+                else {\n+                    push(@bads, [$line]);\n+                }\n+            }\n+            next LINE;\n+        }\n+        # Repository owner can do anything\n+        if ($commit_conf->get_permission_modes()->{'repository'}) {\n+            if (!_perm_ok($commit_conf, $author)) {\n+                # An author who is not a project owner can add paths under the","path":"lib/FCM/Admin/Commit.pm","position":220,"original_position":220,"commit_id":"7b41edc206ff672f519ebd6ba7be89556be6fdc4","original_commit_id":"7b41edc206ff672f519ebd6ba7be89556be6fdc4","user":{"login":"benfitzpatrick","id":1138333,"avatar_url":"https://avatars.githubusercontent.com/u/1138333?v=3","gravatar_id":"","url":"https://api.github.com/users/benfitzpatrick","html_url":"https://github.com/benfitzpatrick","followers_url":"https://api.github.com/users/benfitzpatrick/followers","following_url":"https://api.github.com/users/benfitzpatrick/following{/other_user}","gists_url":"https://api.github.com/users/benfitzpatrick/gists{/gist_id}","starred_url":"https://api.github.com/users/benfitzpatrick/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/benfitzpatrick/subscriptions","organizations_url":"https://api.github.com/users/benfitzpatrick/orgs","repos_url":"https://api.github.com/users/benfitzpatrick/repos","events_url":"https://api.github.com/users/benfitzpatrick/events{/privacy}","received_events_url":"https://api.github.com/users/benfitzpatrick/received_events","type":"User","site_admin":false},"body":"`repository owner`","created_at":"2015-07-27T10:23:16Z","updated_at":"2015-07-27T10:23:16Z","html_url":"https://github.com/metomi/fcm/pull/167#discussion_r35522660","pull_request_url":"https://api.github.com/repos/metomi/fcm/pulls/167","_links":{"self":{"href":"https://api.github.com/repos/metomi/fcm/pulls/comments/35522660"},"html":{"href":"https://github.com/metomi/fcm/pull/167#discussion_r35522660"},"pull_request":{"href":"https://api.github.com/repos/metomi/fcm/pulls/167"}}},"pull_request":{"url":"https://api.github.com/repos/metomi/fcm/pulls/167","id":26901452,"html_url":"https://github.com/metomi/fcm/pull/167","diff_url":"https://github.com/metomi/fcm/pull/167.diff","patch_url":"https://github.com/metomi/fcm/pull/167.patch","issue_url":"https://api.github.com/repos/metomi/fcm/issues/167","number":167,"state":"open","locked":false,"title":"commit hooks: new permission/notification system","user":{"login":"matthewrmshin","id":908613,"avatar_url":"https://avatars.githubusercontent.com/u/908613?v=3","gravatar_id":"","url":"https://api.github.com/users/matthewrmshin","html_url":"https://github.com/matthewrmshin","followers_url":"https://api.github.com/users/matthewrmshin/followers","following_url":"https://api.github.com/users/matthewrmshin/following{/other_user}","gists_url":"https://api.github.com/users/matthewrmshin/gists{/gist_id}","starred_url":"https://api.github.com/users/matthewrmshin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matthewrmshin/subscriptions","organizations_url":"https://api.github.com/users/matthewrmshin/orgs","repos_url":"https://api.github.com/users/matthewrmshin/repos","events_url":"https://api.github.com/users/matthewrmshin/events{/privacy}","received_events_url":"https://api.github.com/users/matthewrmshin/received_events","type":"User","site_admin":false},"body":"The new system is based on simple permission and notification modes at\r\nrepository, project and/or branch level, where owners can be specified.\r\n\r\nLogic is unified in the Perl module `FCM::Admin::Commit`.\r\nNew configuration settings (provisional) are documented at the bottom\r\nof the new module.","created_at":"2015-01-06T16:56:23Z","updated_at":"2015-07-27T10:23:16Z","closed_at":null,"merged_at":null,"merge_commit_sha":"877dc5b8c4bd15388ab07427748454e352a5b715","assignee":{"login":"matthewrmshin","id":908613,"avatar_url":"https://avatars.githubusercontent.com/u/908613?v=3","gravatar_id":"","url":"https://api.github.com/users/matthewrmshin","html_url":"https://github.com/matthewrmshin","followers_url":"https://api.github.com/users/matthewrmshin/followers","following_url":"https://api.github.com/users/matthewrmshin/following{/other_user}","gists_url":"https://api.github.com/users/matthewrmshin/gists{/gist_id}","starred_url":"https://api.github.com/users/matthewrmshin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matthewrmshin/subscriptions","organizations_url":"https://api.github.com/users/matthewrmshin/orgs","repos_url":"https://api.github.com/users/matthewrmshin/repos","events_url":"https://api.github.com/users/matthewrmshin/events{/privacy}","received_events_url":"https://api.github.com/users/matthewrmshin/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/metomi/fcm/milestones/3","html_url":"https://github.com/metomi/fcm/milestones/soon","labels_url":"https://api.github.com/repos/metomi/fcm/milestones/3/labels","id":354884,"number":3,"title":"soon","description":"Issues that will be or need to be resolved soon.","creator":{"login":"matthewrmshin","id":908613,"avatar_url":"https://avatars.githubusercontent.com/u/908613?v=3","gravatar_id":"","url":"https://api.github.com/users/matthewrmshin","html_url":"https://github.com/matthewrmshin","followers_url":"https://api.github.com/users/matthewrmshin/followers","following_url":"https://api.github.com/users/matthewrmshin/following{/other_user}","gists_url":"https://api.github.com/users/matthewrmshin/gists{/gist_id}","starred_url":"https://api.github.com/users/matthewrmshin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matthewrmshin/subscriptions","organizations_url":"https://api.github.com/users/matthewrmshin/orgs","repos_url":"https://api.github.com/users/matthewrmshin/repos","events_url":"https://api.github.com/users/matthewrmshin/events{/privacy}","received_events_url":"https://api.github.com/users/matthewrmshin/received_events","type":"User","site_admin":false},"open_issues":15,"closed_issues":0,"state":"open","created_at":"2013-06-13T14:46:48Z","updated_at":"2015-07-23T10:17:29Z","due_on":"2015-08-30T23:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/metomi/fcm/pulls/167/commits","review_comments_url":"https://api.github.com/repos/metomi/fcm/pulls/167/comments","review_comment_url":"https://api.github.com/repos/metomi/fcm/pulls/comments{/number}","comments_url":"https://api.github.com/repos/metomi/fcm/issues/167/comments","statuses_url":"https://api.github.com/repos/metomi/fcm/statuses/7b41edc206ff672f519ebd6ba7be89556be6fdc4","head":{"label":"matthewrmshin:more-pre-commit","ref":"more-pre-commit","sha":"7b41edc206ff672f519ebd6ba7be89556be6fdc4","user":{"login":"matthewrmshin","id":908613,"avatar_url":"https://avatars.githubusercontent.com/u/908613?v=3","gravatar_id":"","url":"https://api.github.com/users/matthewrmshin","html_url":"https://github.com/matthewrmshin","followers_url":"https://api.github.com/users/matthewrmshin/followers","following_url":"https://api.github.com/users/matthewrmshin/following{/other_user}","gists_url":"https://api.github.com/users/matthewrmshin/gists{/gist_id}","starred_url":"https://api.github.com/users/matthewrmshin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matthewrmshin/subscriptions","organizations_url":"https://api.github.com/users/matthewrmshin/orgs","repos_url":"https://api.github.com/users/matthewrmshin/repos","events_url":"https://api.github.com/users/matthewrmshin/events{/privacy}","received_events_url":"https://api.github.com/users/matthewrmshin/received_events","type":"User","site_admin":false},"repo":{"id":6437763,"name":"fcm","full_name":"matthewrmshin/fcm","owner":{"login":"matthewrmshin","id":908613,"avatar_url":"https://avatars.githubusercontent.com/u/908613?v=3","gravatar_id":"","url":"https://api.github.com/users/matthewrmshin","html_url":"https://github.com/matthewrmshin","followers_url":"https://api.github.com/users/matthewrmshin/followers","following_url":"https://api.github.com/users/matthewrmshin/following{/other_user}","gists_url":"https://api.github.com/users/matthewrmshin/gists{/gist_id}","starred_url":"https://api.github.com/users/matthewrmshin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matthewrmshin/subscriptions","organizations_url":"https://api.github.com/users/matthewrmshin/orgs","repos_url":"https://api.github.com/users/matthewrmshin/repos","events_url":"https://api.github.com/users/matthewrmshin/events{/privacy}","received_events_url":"https://api.github.com/users/matthewrmshin/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/matthewrmshin/fcm","description":"FCM: a modern Fortran build system + wrappers to Subversion for scientific software development","fork":true,"url":"https://api.github.com/repos/matthewrmshin/fcm","forks_url":"https://api.github.com/repos/matthewrmshin/fcm/forks","keys_url":"https://api.github.com/repos/matthewrmshin/fcm/keys{/key_id}","collaborators_url":"https://api.github.com/repos/matthewrmshin/fcm/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/matthewrmshin/fcm/teams","hooks_url":"https://api.github.com/repos/matthewrmshin/fcm/hooks","issue_events_url":"https://api.github.com/repos/matthewrmshin/fcm/issues/events{/number}","events_url":"https://api.github.com/repos/matthewrmshin/fcm/events","assignees_url":"https://api.github.com/repos/matthewrmshin/fcm/assignees{/user}","branches_url":"https://api.github.com/repos/matthewrmshin/fcm/branches{/branch}","tags_url":"https://api.github.com/repos/matthewrmshin/fcm/tags","blobs_url":"https://api.github.com/repos/matthewrmshin/fcm/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/matthewrmshin/fcm/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/matthewrmshin/fcm/git/refs{/sha}","trees_url":"https://api.github.com/repos/matthewrmshin/fcm/git/trees{/sha}","statuses_url":"https://api.github.com/repos/matthewrmshin/fcm/statuses/{sha}","languages_url":"https://api.github.com/repos/matthewrmshin/fcm/languages","stargazers_url":"https://api.github.com/repos/matthewrmshin/fcm/stargazers","contributors_url":"https://api.github.com/repos/matthewrmshin/fcm/contributors","subscribers_url":"https://api.github.com/repos/matthewrmshin/fcm/subscribers","subscription_url":"https://api.github.com/repos/matthewrmshin/fcm/subscription","commits_url":"https://api.github.com/repos/matthewrmshin/fcm/commits{/sha}","git_commits_url":"https://api.github.com/repos/matthewrmshin/fcm/git/commits{/sha}","comments_url":"https://api.github.com/repos/matthewrmshin/fcm/comments{/number}","issue_comment_url":"https://api.github.com/repos/matthewrmshin/fcm/issues/comments{/number}","contents_url":"https://api.github.com/repos/matthewrmshin/fcm/contents/{+path}","compare_url":"https://api.github.com/repos/matthewrmshin/fcm/compare/{base}...{head}","merges_url":"https://api.github.com/repos/matthewrmshin/fcm/merges","archive_url":"https://api.github.com/repos/matthewrmshin/fcm/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/matthewrmshin/fcm/downloads","issues_url":"https://api.github.com/repos/matthewrmshin/fcm/issues{/number}","pulls_url":"https://api.github.com/repos/matthewrmshin/fcm/pulls{/number}","milestones_url":"https://api.github.com/repos/matthewrmshin/fcm/milestones{/number}","notifications_url":"https://api.github.com/repos/matthewrmshin/fcm/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/matthewrmshin/fcm/labels{/name}","releases_url":"https://api.github.com/repos/matthewrmshin/fcm/releases{/id}","created_at":"2012-10-29T09:03:28Z","updated_at":"2015-05-08T11:57:24Z","pushed_at":"2015-07-09T10:50:16Z","git_url":"git://github.com/matthewrmshin/fcm.git","ssh_url":"git@github.com:matthewrmshin/fcm.git","clone_url":"https://github.com/matthewrmshin/fcm.git","svn_url":"https://github.com/matthewrmshin/fcm","homepage":"http://metomi.github.io/fcm/doc/","size":4443,"stargazers_count":2,"watchers_count":2,"language":"Perl","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":2,"default_branch":"master"}},"base":{"label":"metomi:master","ref":"master","sha":"08f0ed35a524dce8862876d4d9215de3c446c94d","user":{"login":"metomi","id":2477494,"avatar_url":"https://avatars.githubusercontent.com/u/2477494?v=3","gravatar_id":"","url":"https://api.github.com/users/metomi","html_url":"https://github.com/metomi","followers_url":"https://api.github.com/users/metomi/followers","following_url":"https://api.github.com/users/metomi/following{/other_user}","gists_url":"https://api.github.com/users/metomi/gists{/gist_id}","starred_url":"https://api.github.com/users/metomi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/metomi/subscriptions","organizations_url":"https://api.github.com/users/metomi/orgs","repos_url":"https://api.github.com/users/metomi/repos","events_url":"https://api.github.com/users/metomi/events{/privacy}","received_events_url":"https://api.github.com/users/metomi/received_events","type":"Organization","site_admin":false},"repo":{"id":6402932,"name":"fcm","full_name":"metomi/fcm","owner":{"login":"metomi","id":2477494,"avatar_url":"https://avatars.githubusercontent.com/u/2477494?v=3","gravatar_id":"","url":"https://api.github.com/users/metomi","html_url":"https://github.com/metomi","followers_url":"https://api.github.com/users/metomi/followers","following_url":"https://api.github.com/users/metomi/following{/other_user}","gists_url":"https://api.github.com/users/metomi/gists{/gist_id}","starred_url":"https://api.github.com/users/metomi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/metomi/subscriptions","organizations_url":"https://api.github.com/users/metomi/orgs","repos_url":"https://api.github.com/users/metomi/repos","events_url":"https://api.github.com/users/metomi/events{/privacy}","received_events_url":"https://api.github.com/users/metomi/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/metomi/fcm","description":"FCM: a modern Fortran build system + wrappers to Subversion for scientific software development","fork":false,"url":"https://api.github.com/repos/metomi/fcm","forks_url":"https://api.github.com/repos/metomi/fcm/forks","keys_url":"https://api.github.com/repos/metomi/fcm/keys{/key_id}","collaborators_url":"https://api.github.com/repos/metomi/fcm/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/metomi/fcm/teams","hooks_url":"https://api.github.com/repos/metomi/fcm/hooks","issue_events_url":"https://api.github.com/repos/metomi/fcm/issues/events{/number}","events_url":"https://api.github.com/repos/metomi/fcm/events","assignees_url":"https://api.github.com/repos/metomi/fcm/assignees{/user}","branches_url":"https://api.github.com/repos/metomi/fcm/branches{/branch}","tags_url":"https://api.github.com/repos/metomi/fcm/tags","blobs_url":"https://api.github.com/repos/metomi/fcm/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/metomi/fcm/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/metomi/fcm/git/refs{/sha}","trees_url":"https://api.github.com/repos/metomi/fcm/git/trees{/sha}","statuses_url":"https://api.github.com/repos/metomi/fcm/statuses/{sha}","languages_url":"https://api.github.com/repos/metomi/fcm/languages","stargazers_url":"https://api.github.com/repos/metomi/fcm/stargazers","contributors_url":"https://api.github.com/repos/metomi/fcm/contributors","subscribers_url":"https://api.github.com/repos/metomi/fcm/subscribers","subscription_url":"https://api.github.com/repos/metomi/fcm/subscription","commits_url":"https://api.github.com/repos/metomi/fcm/commits{/sha}","git_commits_url":"https://api.github.com/repos/metomi/fcm/git/commits{/sha}","comments_url":"https://api.github.com/repos/metomi/fcm/comments{/number}","issue_comment_url":"https://api.github.com/repos/metomi/fcm/issues/comments{/number}","contents_url":"https://api.github.com/repos/metomi/fcm/contents/{+path}","compare_url":"https://api.github.com/repos/metomi/fcm/compare/{base}...{head}","merges_url":"https://api.github.com/repos/metomi/fcm/merges","archive_url":"https://api.github.com/repos/metomi/fcm/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/metomi/fcm/downloads","issues_url":"https://api.github.com/repos/metomi/fcm/issues{/number}","pulls_url":"https://api.github.com/repos/metomi/fcm/pulls{/number}","milestones_url":"https://api.github.com/repos/metomi/fcm/milestones{/number}","notifications_url":"https://api.github.com/repos/metomi/fcm/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/metomi/fcm/labels{/name}","releases_url":"https://api.github.com/repos/metomi/fcm/releases{/id}","created_at":"2012-10-26T11:41:46Z","updated_at":"2015-05-08T11:57:29Z","pushed_at":"2015-07-09T10:50:10Z","git_url":"git://github.com/metomi/fcm.git","ssh_url":"git@github.com:metomi/fcm.git","clone_url":"https://github.com/metomi/fcm.git","svn_url":"https://github.com/metomi/fcm","homepage":"http://metomi.github.io/fcm/doc/","size":4420,"stargazers_count":13,"watchers_count":13,"language":"Perl","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":10,"mirror_url":null,"open_issues_count":44,"forks":10,"open_issues":44,"watchers":13,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/metomi/fcm/pulls/167"},"html":{"href":"https://github.com/metomi/fcm/pull/167"},"issue":{"href":"https://api.github.com/repos/metomi/fcm/issues/167"},"comments":{"href":"https://api.github.com/repos/metomi/fcm/issues/167/comments"},"review_comments":{"href":"https://api.github.com/repos/metomi/fcm/pulls/167/comments"},"review_comment":{"href":"https://api.github.com/repos/metomi/fcm/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/metomi/fcm/pulls/167/commits"},"statuses":{"href":"https://api.github.com/repos/metomi/fcm/statuses/7b41edc206ff672f519ebd6ba7be89556be6fdc4"}}}}