The branch, master on karma.git has been updated
via 002a63c12dc1eadb3885d9fc5c6b97cf3863913a (commit)
via f3d11575dc77ab1cc7eda290a4366122b923b1c1 (commit)
via 51ca66d43a28b1c50cfd4e994712bc577e440e52 (commit)
via c358027fd70d57b60f12b620dc78f6fe7c384aec (commit)
from 8d595325d65b7de86651483a1705a0ee2a4b4bd5 (commit)
http://git.php.net/?p=karma.git;a=log;h=002a63c12dc1eadb3885d9fc5c6b97cf3863913a;hp=8d595325d65b7de86651483a1705a0ee2a4b4bd5
Summary of changes:
hooks/pre-receive | 29 +++++++++-----
lib/Git.php | 25 ++++++++++++
lib/Git/PushInformation.php | 86 +++++++++++++++++++++++++++++++++++++++++++
lib/Git/ReceiveHook.php | 43 +++++++++------------
4 files changed, 148 insertions(+), 35 deletions(-)
create mode 100644 lib/Git.php
create mode 100644 lib/Git/PushInformation.php
-- Log ----------------------------------------
commit 002a63c12dc1eadb3885d9fc5c6b97cf3863913a
Author: David Soria Parra <[email protected]>
Date: Fri Mar 2 03:06:30 2012 +0100
Require access to all the repository in case we do a forced push
A forced push can happen when you delete a tag or rewrite commits. We allow
this, but only if you have access to the root of the repository.
diff --git a/hooks/pre-receive b/hooks/pre-receive
index 46195a4..48da31b 100755
--- a/hooks/pre-receive
+++ b/hooks/pre-receive
@@ -11,11 +11,15 @@ namespace Karma;
const KARMA_FILE = '/git/checkout/SVNROOT/global_avail';
const REPOSITORY_PATH = '/git/repositories';
+const LIB_PATH = '/git/checkout/karma/lib';
-set_include_path('/git/checkout/karma/lib' .
+set_include_path(
+ getenv('KARMA_LIB_PATH') ?: LIB_PATH .
PATH_SEPARATOR .
get_include_path());
+include 'Git.php';
+include 'Git/PushInformation.php';
include 'Git/ReceiveHook.php';
function deny($reason)
@@ -107,16 +111,19 @@ if ($hook->isKarmaIgnored()) {
accept("No karma check necessary. Thank you for your contribution.\n");
}
-$requested_paths = $hook->getReceivedPaths();
+$repo_name = $hook->getRepositoryName();
+$pi = new \Git\PushInformation($hook);
+$req_paths = ($pi->isForced()) ? [''] : $hook->getReceivedPaths();
+var_dump($pi->isForced());
-if (empty($requested_paths)) {
+if (empty($req_paths)) {
deny("We cannot figure out what you comitted!");
}
-$prefix = sprintf('%s/', $hook->getRepositoryName());
+$prefix = sprintf('%s/', $repo_name);
$avail_lines = $hook->getKarmaFile();
-$requested_paths = array_map(function ($x) use ($prefix) { return $prefix .
$x;}, $requested_paths);
-$unavail_paths = get_unavail_paths($user, $requested_paths, $avail_lines);
+$req_paths = array_map(function ($x) use ($prefix) { return $prefix .
$x;}, $req_paths);
+$unavail_paths = get_unavail_paths($user, $req_paths, $avail_lines);
if (!empty($unavail_paths)) {
deny(sprintf(
diff --git a/lib/Git/PushInformation.php b/lib/Git/PushInformation.php
new file mode 100644
index 0000000..edf73dc
--- /dev/null
+++ b/lib/Git/PushInformation.php
@@ -0,0 +1,86 @@
+<?php
+namespace Git;
+
+class PushInformation
+{
+ const GIT_EXECUTABLE = 'git';
+
+ private $karmaFile;
+ private $repositoryBasePath;
+
+ private $hook = null;
+ private $repourl = null;
+
+ public function __construct(ReceiveHook $hook)
+ {
+ $this->repourl = \Git::getRepositoryPath();
+ $this->hook = $hook;
+ }
+
+ /**
+ * Returns the common ancestor revision for two given revisions
+ *
+ * Returns false if no sha1 was returned. Throws an exception if calling
+ * git fails.
+ *
+ * @return boolean
+ */
+ protected function mergeBase($oldrev, $newrev)
+ {
+ $baserev = exec(sprintf('%s --git-dir=%s merge-base %s %s',
+ \Git::GIT_EXECUTABLE,
+ $this->repourl,
+ escapeshellarg($oldrev),
+ escapeshellarg($newrev)), $output, $retval);
+
+ $baserev = trim($baserev);
+
+ if (0 !== $retval) {
+ throw new \Exception('Failed to call git');
+ }
+
+ if (40 != strlen($baserev)) {
+ return false;
+ }
+
+ return $baserev;
+ }
+
+ /**
+ * Returns true if merging $newrev would be fast forward
+ *
+ * @return boolean
+ */
+ public function isFastForward()
+ {
+ $result = $this->hook->mapInput(
+ function ($oldrev, $newrev) {
+ if ($oldrev == \Git::NULLREV) {
+ return true;
+ }
+ return $oldrev == $this->mergeBase($oldrev, $newrev);
+ });
+
+ return array_reduce($result, function($a, $b) { return $a && $b; },
true);
+ }
+
+ /**
+ * Returns true if updating the refs would fail if push is not forced.
+ *
+ * @return boolean
+ */
+ public function isForced()
+ {
+ $result = $this->hook->mapInput(
+ function($oldrev, $newrev) {
+ if ($oldrev == \Git::NULLREV) {
+ return false;
+ } else if ($newrev == \Git::NULLREV) {
+ return true;
+ }
+ return $newrev == $this->mergeBase($oldrev, $newrev);
+ });
+
+ return array_reduce($result, function($a, $b) { return $a || $b; },
false);
+ }
+}
diff --git a/lib/Git/ReceiveHook.php b/lib/Git/ReceiveHook.php
index e17d055..b51a5f4 100644
--- a/lib/Git/ReceiveHook.php
+++ b/lib/Git/ReceiveHook.php
@@ -42,6 +42,15 @@ class ReceiveHook
return '';
}
+ public function mapInput(callable $fn) {
+ $result = [];
+ foreach($this->hookInput() as $input) {
+ $result[] = $fn($input['old'], $input['new']);
+ }
+
+ return $result;
+ }
+
/**
* Parses the input from git.
*
@@ -100,12 +109,12 @@ class ReceiveHook
sprintf("%s --git-dir=%s for-each-ref --format='%%(refname)'
'refs/heads/*'",
\Git::GIT_EXECUTABLE, $repourl), $output);
/* do we have heads? otherwise it's a new repo! */
- $heads = implode(' ', $output);
if (count($output) > 0) {
$not = array_map(
function($x) {
return sprintf('--not %s', escapeshellarg($x));
- }, $heads);
+ }, $output);
+ $not = implode(' ', $not);
}
exec(
sprintf('%s --git-dir=%s log --name-only --pretty=format:"" %s
%s',
Thank you for your contribution.
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php