composer update
This commit is contained in:
1
vendor/gitonomy/gitlib/.gitattributes
vendored
Normal file
1
vendor/gitonomy/gitlib/.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
* text=auto
|
3
vendor/gitonomy/gitlib/.gitignore
vendored
Normal file
3
vendor/gitonomy/gitlib/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/vendor
|
||||
/composer.lock
|
||||
/phpunit.xml
|
26
vendor/gitonomy/gitlib/.travis.yml
vendored
Normal file
26
vendor/gitonomy/gitlib/.travis.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
language: php
|
||||
|
||||
sudo: false
|
||||
|
||||
php:
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7.0
|
||||
- 7.1
|
||||
- 7.2
|
||||
- hhvm
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- php: 5.3
|
||||
dist: precise
|
||||
|
||||
before_install:
|
||||
# turn off XDebug, if present
|
||||
- phpenv config-rm xdebug.ini || return 0
|
||||
|
||||
install:
|
||||
- composer install --no-interaction --no-progress
|
||||
|
||||
script: vendor/bin/phpunit
|
20
vendor/gitonomy/gitlib/LICENSE
vendored
Normal file
20
vendor/gitonomy/gitlib/LICENSE
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
Copyright (c) 2012 Alexandre Salomé
|
||||
Copyright (c) 2012 Julien DIDIER
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
12
vendor/gitonomy/gitlib/README.md
vendored
Normal file
12
vendor/gitonomy/gitlib/README.md
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
Git lib for Gitonomy
|
||||
====================
|
||||
|
||||
[](https://travis-ci.org/gitonomy/gitlib)
|
||||
|
||||
This library provides methods to access Git repository from PHP.
|
||||
|
||||
It makes shell calls, which makes it less performant than any solution.
|
||||
|
||||
Anyway, it's convenient and don't need to build anything to use it. That's how we love it.
|
||||
|
||||
*Documentation*: http://gitonomy.com/doc/gitlib/master/
|
44
vendor/gitonomy/gitlib/composer.json
vendored
Normal file
44
vendor/gitonomy/gitlib/composer.json
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "gitonomy/gitlib",
|
||||
"description": "Library for accessing git",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Alexandre Salomé",
|
||||
"email": "alexandre.salome@gmail.com",
|
||||
"homepage": "http://alexandre-salome.fr"
|
||||
},
|
||||
{
|
||||
"name": "Julien DIDIER",
|
||||
"email": "genzo.wm@gmail.com",
|
||||
"homepage": "http://www.jdidier.net"
|
||||
}
|
||||
],
|
||||
"homepage": "http://gitonomy.com",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Gitonomy\\Git\\": "src/Gitonomy/Git/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Gitonomy\\Git\\Tests\\": "tests/Gitonomy/Git/Tests/"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.3 || ^7.0",
|
||||
"symfony/process": "^2.3|^3.0|^4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35|^5.7",
|
||||
"psr/log": "^1.0"
|
||||
},
|
||||
"suggest": {
|
||||
"psr/log": "Add some log"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
}
|
||||
}
|
||||
}
|
76
vendor/gitonomy/gitlib/doc/api/admin.rst
vendored
Normal file
76
vendor/gitonomy/gitlib/doc/api/admin.rst
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
Create and access git repositories
|
||||
==================================
|
||||
|
||||
gitlib provides methods to initialize new repositories.
|
||||
|
||||
Create a repository
|
||||
-------------------
|
||||
|
||||
To initialize a new repository, use method ``Admin::init``.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
// Initialize a bare repository
|
||||
$repository = Gitonomy\Git\Admin::init('/path/to/repository');
|
||||
|
||||
// Initialize a non-bare repository
|
||||
$repository = Gitonomy\Git\Admin::init('/path/to/repository', false);
|
||||
|
||||
Default behavior is to create a bare repository. If you want to initialize a
|
||||
repository with a working copy,pass ``false`` as third argument of Repository
|
||||
constructor.
|
||||
|
||||
Cloning repositories
|
||||
--------------------
|
||||
|
||||
You can clone a repository from an URL by doing:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
// Clone to a bare repository
|
||||
$repository = Gitonomy\Git\Admin::cloneTo('/tmp/gitlib', 'https://github.com/gitonomy/gitlib.git');
|
||||
|
||||
// Clone to a non-bare repository
|
||||
$repository = Gitonomy\Git\Admin::cloneTo('/tmp/gitlib', 'https://github.com/gitonomy/gitlib.git', false);
|
||||
|
||||
Default behavior is to clone in a bare repository.
|
||||
|
||||
You can also clone a repository and point it to a specific branch. In a non-bare repository, this branch will be checked out:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
// Clone to a bare repository
|
||||
$repository = Gitonomy\Git\Admin::cloneBranchTo('/tmp/gitlib', 'https://github.com/gitonomy/gitlib.git', 'a-branch');
|
||||
|
||||
// Clone to a non-bare repository
|
||||
$repository = Gitonomy\Git\Admin::cloneBranchTo('/tmp/gitlib', 'https://github.com/gitonomy/gitlib.git', 'a-branch' false);
|
||||
|
||||
Clone a Repository object
|
||||
-------------------------
|
||||
|
||||
If you already have a Repository instance and want to clone it, you can use this shortcut:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$new = $repository->cloneTo('/tmp/clone');
|
||||
|
||||
Mirror a repository
|
||||
-------------------
|
||||
|
||||
If you want to mirror fully a repository and all references, use the ``mirrorTo`` method. This method
|
||||
takes only two arguments, where to mirror and what to mirror:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
// Mirror to a bare repository
|
||||
$mirror = Gitonomy\Git\Admin::mirrorTo('/tmp/mirror', 'https://github.com/gitonomy/gitlib.git');
|
||||
|
||||
// Mirror to a non-bare repository
|
||||
$mirror = Gitonomy\Git\Admin::mirrorTo('/tmp/mirror', 'https://github.com/gitonomy/gitlib.git', false);
|
||||
|
||||
|
||||
References
|
||||
::::::::::
|
||||
|
||||
* http://linux.die.net/man/1/git-init
|
||||
* http://linux.die.net/man/1/git-clone
|
54
vendor/gitonomy/gitlib/doc/api/blame.rst
vendored
Normal file
54
vendor/gitonomy/gitlib/doc/api/blame.rst
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
Blaming files
|
||||
=============
|
||||
|
||||
Line-per-line iteration
|
||||
-----------------------
|
||||
|
||||
To iterate on lines of a blame:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$blame = $repository->getBlame('master', 'README.md');
|
||||
|
||||
foreach ($blame->getLines() as $lineNumber => $line) {
|
||||
$commit = $line->getCommit();
|
||||
echo $lineNumber.': '.$line->getContent()." - ".$commit->getAuthorName()."\n";
|
||||
}
|
||||
|
||||
The *getLines* method returns an array indexed starting from 1.
|
||||
|
||||
As you can see, you can access the commit object related to the line you are iterating on.
|
||||
|
||||
If you want to access directly a line:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$line = $blame->getLine(32);
|
||||
|
||||
The Line object
|
||||
---------------
|
||||
|
||||
LineObject represents an item of the blame file. It is composed of those informations:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$line->getCommit(); // returns a Commit
|
||||
$line->getContent(); // returns text
|
||||
|
||||
// you can access author from commmit:
|
||||
$author = $line->getCommit()->getAuthorName();
|
||||
|
||||
Group reading by commit
|
||||
-----------------------
|
||||
|
||||
If you plan to display it, you'll probably need a version where lines from same commit are grouped.
|
||||
|
||||
To do so, use the *getGroupedLines* method that will return an array like this:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$blame = array(
|
||||
array(Commit, array(1 => Line, 2 => Line, 3 => Line)),
|
||||
array(Commit, array(4 => Line)),
|
||||
array(Commit, array(5 => Line, 6 => Line))
|
||||
)
|
44
vendor/gitonomy/gitlib/doc/api/blob.rst
vendored
Normal file
44
vendor/gitonomy/gitlib/doc/api/blob.rst
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
Blob
|
||||
====
|
||||
|
||||
In git, a blob represents a file content. You can't access the file name
|
||||
directly from the *Blob* object; the filename information is stored within
|
||||
the tree, not in the blob.
|
||||
|
||||
It means that for git, two files with different names but same content will
|
||||
have the same hash.
|
||||
|
||||
To access a repository *Blob*, you need the hash identifier:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$repository = new Gitonomy\Git\Repository('/path/to/repository');
|
||||
$blob = $repository->getBlob('a7c8d2b4');
|
||||
|
||||
Get content
|
||||
-----------
|
||||
|
||||
To get content from a *Blob* object:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
echo $blob->getContent();
|
||||
|
||||
File informations
|
||||
-----------------
|
||||
|
||||
To get mimetype of a *Blob* object using finfo extension:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
echo $blob->getMimetype();
|
||||
|
||||
You can also test if *Blob* is a text of a binary file:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
if ($blob->isText()) {
|
||||
echo $blob->getContent(), "\n";
|
||||
} elseif ($blob->isBinary()) {
|
||||
echo "File is binary\n";
|
||||
}
|
16
vendor/gitonomy/gitlib/doc/api/branch.rst
vendored
Normal file
16
vendor/gitonomy/gitlib/doc/api/branch.rst
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
Branch
|
||||
======
|
||||
|
||||
To access a *Branch*, starting from a repository object:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$repository = new Gitonomy\Git\Repository('/path/to/repository');
|
||||
$branch = $repository->getReferences()->getBranch('master');
|
||||
|
||||
You can check is the branch is a local or remote one:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$branch->isLocal();
|
||||
$branch->isRemote();
|
168
vendor/gitonomy/gitlib/doc/api/commit.rst
vendored
Normal file
168
vendor/gitonomy/gitlib/doc/api/commit.rst
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
Commit
|
||||
======
|
||||
|
||||
To access a *Commit*, starting from a repository object:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$repository = new Gitonomy\Git\Repository('/path/to/repository');
|
||||
$commit = $repository->getCommit('a7c8d2b4');
|
||||
|
||||
Browsing parents
|
||||
----------------
|
||||
|
||||
A *Commit* can have a natural number of parents:
|
||||
|
||||
* **no parent**: it's an initial commit, the root of a tree
|
||||
* **one parent**: it means it's not a merge, just a regular commit
|
||||
* **many parents**: it's a merge-commit
|
||||
|
||||
You have 2 methods available for accessing parents:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
// Access parent hashes
|
||||
$hashes = $commit->getParentHashes();
|
||||
|
||||
// Access parent commit objects
|
||||
$commits = $commit->getParents();
|
||||
|
||||
For example, if you want to display all parents, starting from a commit:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
function displayLog(Gitonomy\Git\Commit $commit) {
|
||||
echo '- '.$commit->getShortMessage()."\n";
|
||||
foreach ($commit->getParents() as $parent) {
|
||||
displayLog($parent);
|
||||
}
|
||||
}
|
||||
|
||||
Notice that this function will first display all commits from first merged
|
||||
branch and then display all commits from next branch, and so on.
|
||||
|
||||
Accessing tree
|
||||
--------------
|
||||
|
||||
The tree object contains the reference to the files associated to a given
|
||||
commit. Every commit has one and only one tree, referencing all files and
|
||||
folders of a given state for a project. For more informations about the tree,
|
||||
see the chapter dedicated to it.
|
||||
|
||||
To access a tree starting from a commit:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
// Returns the tree hash
|
||||
$tree = $commit->getTreeHash();
|
||||
|
||||
// Returns the tree object
|
||||
$tree = $commit->getTree();
|
||||
|
||||
Author & Committer informations
|
||||
-------------------------------
|
||||
|
||||
Each commit has two authoring informations: an author and a committer. The
|
||||
author is the creator of the modification, authoring a modification in the
|
||||
repository. The committer is responsible of introducing this modification to
|
||||
the repository.
|
||||
|
||||
You can access informations from author and committer using those methods:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
// Author
|
||||
$commit->getAuthorName();
|
||||
$commit->getAuthorEmail();
|
||||
$commit->getAuthorDate(); // returns a DateTime object
|
||||
|
||||
// Committer
|
||||
$commit->getCommitterName();
|
||||
$commit->getCommitterEmail();
|
||||
$commit->getCommitterDate(); // returns a DateTime object
|
||||
|
||||
Commit message and short message
|
||||
--------------------------------
|
||||
|
||||
Each commit also has a message, associated to the modification. This message
|
||||
can be multilined.
|
||||
|
||||
To access the message, you can use the *getMessage* method:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$commit->getMessage();
|
||||
|
||||
For your convenience, this library provides a shortcut method to keep only the
|
||||
first line or first 50 characters if the first line is too long:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$commit->getShortMessage();
|
||||
|
||||
You can customize it like this:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$commit->getShortMessage(45, true, '.');
|
||||
|
||||
* The first parameter is the max length of the message.
|
||||
* The second parameter determine if the last word should be cut or preserved
|
||||
* The third parameter is the separator
|
||||
|
||||
There are also two other methods for your convenience:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
// The first line
|
||||
$commit->getSubjectMessage();
|
||||
|
||||
// The body (rest of the message)
|
||||
$commit->getBodyMessage();
|
||||
|
||||
Diff of a commit
|
||||
----------------
|
||||
|
||||
You can check the modifications introduced by a commit using the *getDiff*
|
||||
method. When you request a diff for a commit, depending of the number of
|
||||
parents, the strategy will be different:
|
||||
|
||||
* If you have *no parent*, the diff will be the content of the tree
|
||||
* If you only have *one parent*, the diff will be between the commit and his
|
||||
parent
|
||||
* If you have *multiple parents*, the diff will be the difference between the
|
||||
commit and the first common ancestor of all parents
|
||||
|
||||
For more informations about the diff API, read the related chapter.
|
||||
|
||||
To access the *Diff* object of a commit, use the method *getDiff*:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$diff = $commit->getDiff();
|
||||
|
||||
Last modification of a file
|
||||
---------------------------
|
||||
|
||||
To know the last modification of a file, you can use the *getLastModification*
|
||||
method on a commit.
|
||||
|
||||
Here is a very straightforward example:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$last = $commit->getLastModification('README');
|
||||
|
||||
echo "Last README modification:\n";
|
||||
echo" Author: ".$last->getAuthorName()."\n";
|
||||
echo" Date: ".$last->getAuthorDate()->format('d/m/Y')."\n";
|
||||
echo" Message: ".$last->getMessage();
|
||||
|
||||
Find every branches containing a commit
|
||||
---------------------------------------
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$branches = $commit->getIncludingBranches($includeLocalBranches, $includeRemoteBranches);
|
||||
$localBranches = $commit->getIncludingBranches(true, false);
|
||||
$remoteBranches = $commit->getIncludingBranches(false, true);
|
102
vendor/gitonomy/gitlib/doc/api/diff.rst
vendored
Normal file
102
vendor/gitonomy/gitlib/doc/api/diff.rst
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
Computing diff
|
||||
==============
|
||||
|
||||
Even if git is a diff-less storage engine, it's possible to compute them.
|
||||
|
||||
To compute a diff in git, you need to specify a *revision*. This revision can
|
||||
be a commit (*2bc7a8*) or a range (*2bc7a8..ff4c21b*).
|
||||
|
||||
For more informations about git revisions: *man gitrevisions*.
|
||||
|
||||
When you have decided the revision you want and have your *Repository* object,
|
||||
you can call the *getDiff* method on the repository:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$diff = $repository->getDiff('master@{2 days ago}..master');
|
||||
|
||||
You can also access it from a *Log* object:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$log = $repository->getLog('master@{2 days ago}..master');
|
||||
$diff = $log->getDiff();
|
||||
|
||||
Iterating a diff
|
||||
----------------
|
||||
|
||||
When you have a *Diff* object, you can iterate over files using method
|
||||
*getFiles()*. This method returns a list of *File* objects, who represents the
|
||||
modifications for a single file.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$files = $diff->getFiles();
|
||||
echo sprintf("%s files modified", count($files));
|
||||
|
||||
foreach ($files as $fileDiff) {
|
||||
echo sprintf("Old name: (%s) %s\n", $fileDiff->getOldMode(), $fileDiff->getOldName());
|
||||
echo sprintf("New name: (%s) %s\n", $fileDiff->getNewMode(), $fileDiff->getNewName());
|
||||
}
|
||||
|
||||
The File object
|
||||
---------------
|
||||
|
||||
Here is an exhaustive list of the *File* class methods:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$file->getOldName();
|
||||
$file->getNewName();
|
||||
$file->getOldDiff();
|
||||
$file->getNewDiff();
|
||||
|
||||
$file->isCreation();
|
||||
$file->isDeletion();
|
||||
$file->isModification();
|
||||
|
||||
$file->isRename();
|
||||
$file->isChangeMode();
|
||||
|
||||
$file->getAdditions(); // Number of added lines
|
||||
$file->getDeletions(); // Number of deleted lines
|
||||
|
||||
$file->isBinary(); // Binary files have no "lines"
|
||||
|
||||
$file->getChanges(); // See next chapter
|
||||
|
||||
The FileChange object
|
||||
---------------------
|
||||
|
||||
.. note::
|
||||
|
||||
This part of API is not very clean, very consistent. If you have any idea
|
||||
or suggestion on how to enhance this, your comment would be appreciated.
|
||||
|
||||
A *File* object is composed of many changes. For each of those changes,
|
||||
a *FileChange* object is associated.
|
||||
|
||||
To access changes from a file, use the *getChanges* method:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$changes = $file->getChanges();
|
||||
foreach ($changes as $change) {
|
||||
foreach ($lines as $data) {
|
||||
list ($type, $line) = $data;
|
||||
if ($type === FileChange::LINE_CONTEXT) {
|
||||
echo ' '.$line."\n";
|
||||
} elseif ($type === FileChange::LINE_ADD) {
|
||||
echo '+'.$line."\n";
|
||||
} else {
|
||||
echo '-'.$line."\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
To get line numbers, use the range methods:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
echo sprintf("Previously from line %s to %s\n", $change->getOldRangeStart(), $change->getOldRangeEnd());
|
||||
echo sprintf("Now from line %s to %s\n", $change->getNewRangeStart(), $change->getNewRangeEnd());
|
76
vendor/gitonomy/gitlib/doc/api/hooks.rst
vendored
Normal file
76
vendor/gitonomy/gitlib/doc/api/hooks.rst
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
Hooks
|
||||
=====
|
||||
|
||||
It's possible to define custom hooks on any repository with git. Those hooks
|
||||
are located in the *.git/hooks* folder.
|
||||
|
||||
Those files need to be executable. For convenience, gitlib will set them to
|
||||
*777*.
|
||||
|
||||
With *gitlib*, you can manage hooks over a repository using the *Hooks* object.
|
||||
|
||||
To access it from a repository, use the *getHooks* method on a *Repository*
|
||||
object:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$hooks = $repository->getHooks();
|
||||
|
||||
Reading hooks
|
||||
-------------
|
||||
|
||||
To read the content of a hook, use the *get* method like this:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$content = $hooks->get('pre-receive'); // returns a string
|
||||
|
||||
If the hook does not exist, an exception will be thrown (*InvalidArgumentException*).
|
||||
|
||||
You can test if a hook is present using the method *has*:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$hooks->has('pre-receive'); // a boolean indicating presence
|
||||
|
||||
Inserting hooks
|
||||
---------------
|
||||
|
||||
You can modify a hook in two different ways: creating a new file or using a symlink.
|
||||
|
||||
To create the hook using a symlink:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$hooks->setSymlink('pre-receive', '/path/to/file-to-link');
|
||||
|
||||
If the hook already exist, a *LogicException* will be thrown. If an error occured
|
||||
during symlink creation, a *RuntimeException* will be thrown.
|
||||
|
||||
If you want to directly create a new file in hooks directory, use the
|
||||
method *set*. This method will create a new file, put content in it and make it
|
||||
executable:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$content = <<<HOOK
|
||||
#!/bin/bash
|
||||
echo "Push is disabled"
|
||||
exit 1
|
||||
|
||||
HOOK;
|
||||
|
||||
// this hook will reject every push
|
||||
|
||||
$hooks->set('pre-receive', $content);
|
||||
|
||||
If the hook already exists, a *LogicException* will be thrown.
|
||||
|
||||
Removing hooks
|
||||
--------------
|
||||
|
||||
To remove a hook from a repository, use the function *remove*:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$hooks->remove('pre-receive');
|
54
vendor/gitonomy/gitlib/doc/api/log.rst
vendored
Normal file
54
vendor/gitonomy/gitlib/doc/api/log.rst
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
Getting log history
|
||||
===================
|
||||
|
||||
Crawling manually commits and parents to browse history is surely a good
|
||||
solution. But when it comes to ordering them or aggregate them from multiple
|
||||
branches, we tend to use ``git log``.
|
||||
|
||||
To get a *Log* object from a repository:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$log = $repository->getLog();
|
||||
|
||||
You can pass four arguments to *getLog* method:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
// Global log for repository
|
||||
$log = $repository->getLog();
|
||||
|
||||
// Log for master branch
|
||||
$log = $repository->getLog('master');
|
||||
|
||||
// Returns last 10 commits on README file
|
||||
$log = $repository->getLog('master', 'README', 0, 10);
|
||||
|
||||
// Returns last 10 commits on README or UPGRADE files
|
||||
$log = $repository->getLog('master', array('README', 'UPGRADE'), 0, 10);
|
||||
|
||||
Counting
|
||||
--------
|
||||
|
||||
If you want to count overall commits, without offset or limit, use the *countCommits* method:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
echo sprintf("This log contains %s commits\n", $log->countCommits());
|
||||
|
||||
// Countable interface
|
||||
echo sprintf("This log contains %s commits\n", count($log));
|
||||
|
||||
Offset and limit
|
||||
----------------
|
||||
|
||||
Use those methods:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$log->setOffset(32);
|
||||
$log->setLimit(40);
|
||||
|
||||
// or read it:
|
||||
$log->getOffset();
|
||||
$log->getLimit();
|
91
vendor/gitonomy/gitlib/doc/api/references.rst
vendored
Normal file
91
vendor/gitonomy/gitlib/doc/api/references.rst
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
Tags and branches
|
||||
=================
|
||||
|
||||
Accessing tags and branches
|
||||
---------------------------
|
||||
|
||||
With *gitlib*, you can access them via the *ReferenceBag* object. To get this
|
||||
object from a *Repository*, use the *getReferences* method:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$references = $repository->getReferences();
|
||||
|
||||
First, you can test existence of tags and branches like this:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
if ($references->hasBranch('master') && $references->hasTag('0.1')) {
|
||||
echo "Good start!";
|
||||
}
|
||||
|
||||
If you want to access all branches or all tags:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$branches = $references->getBranches();
|
||||
$localBranches = $references->getLocalBranches();
|
||||
$remoteBranches = $references->getRemoteBranches();
|
||||
$tags = $references->getTags();
|
||||
$all = $references->getAll();
|
||||
|
||||
To get a given branch or tag, call *getBranch* or *getTag* on the
|
||||
*ReferenceBag*. Those methods return *Branch* and *Tag* objects:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$master = $references->getBranch('master');
|
||||
$feat123 = $references->getLocalBranch('feat123');
|
||||
$feat456 = $references->getRemoteBranch('origin/feat456');
|
||||
$v0_1 = $references->getTag('0.1');
|
||||
|
||||
If the reference cannot be resolved, a *ReferenceNotFoundException* will be
|
||||
thrown.
|
||||
|
||||
On each of those objects, you can access those informations:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
// Get the associated commit
|
||||
$commit = $master->getCommit();
|
||||
|
||||
// Get the commit hash
|
||||
$hash = $master->getCommitHash();
|
||||
|
||||
// Get the last modification
|
||||
$lastModification = $master->getLastModification();
|
||||
|
||||
Create and delete reference
|
||||
---------------------------
|
||||
|
||||
You can create new tags and branches on repository, using helper methods
|
||||
on ReferenceBag object:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
// create a branch
|
||||
$references = $repository->getReferences();
|
||||
$branch = $references->createBranch('foobar', 'a8b7e4...'); // commit to reference
|
||||
|
||||
// create a tag
|
||||
$references = $repository->getReferences();
|
||||
$tag = $references->createTag('0.3', 'a8b7e4...'); // commit to reference
|
||||
|
||||
// delete a branch or a tag
|
||||
$branch->delete();
|
||||
|
||||
Resolution from a commit
|
||||
------------------------
|
||||
|
||||
To resolve a branch or a commit from a commit, you can use the *resolveTags*
|
||||
and *resolveBranches* methods on it:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$branches = $references->resolveBranches($commit);
|
||||
$tags = $references->resolveTags($commit);
|
||||
|
||||
// Resolve branches and tags
|
||||
$all = $references->resolve($commit);
|
||||
|
||||
You can pass a *Commit* object or a hash to the method, gitlib will handle it.
|
135
vendor/gitonomy/gitlib/doc/api/repository.rst
vendored
Normal file
135
vendor/gitonomy/gitlib/doc/api/repository.rst
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
Repository methods
|
||||
==================
|
||||
|
||||
Creating a *Repository* object is possible, providing a *path* argument to the
|
||||
constructor:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$repository = new Repository('/path/to/repo');
|
||||
|
||||
Repository options
|
||||
------------------
|
||||
|
||||
The constructor of Repository takes an additional parameter: ``$options``.
|
||||
This parameter can be used used to tune behavior of library.
|
||||
|
||||
Available options are:
|
||||
|
||||
* **debug** (default: true): Enables exception when edge cases are met
|
||||
* **environment_variables**: (default: none) An array of environment variables to be set in sub-process
|
||||
* **logger**: (default: none) Logger to use for reporting of execution (a ``Psr\Log\LoggerInterface``)
|
||||
* **command**: (default: ``git``) Specify command to execute to run git
|
||||
* **working_dir**: If you are using multiple working directories, this option is for you
|
||||
|
||||
An example:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$repository = new Repository('/path/to/repo', array(
|
||||
'debug' => true,
|
||||
'logger' => new Monolog\Logger()
|
||||
));
|
||||
|
||||
Test if a repository is bare
|
||||
----------------------------
|
||||
|
||||
On a *Repository* object, you can call method *isBare* to test if your repository is bare or not:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$repository->isBare();
|
||||
|
||||
Compute size of a repository
|
||||
----------------------------
|
||||
|
||||
To know how much size a repository is using on your drive, you can use ``getSize`` method on a *Repository* object.
|
||||
|
||||
.. warning:: This command was only tested with linux.
|
||||
|
||||
The returned size is in kilobytes:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$size = $repository->getSize();
|
||||
|
||||
echo "Your repository size is ".$size."KB";
|
||||
|
||||
Access HEAD
|
||||
-----------
|
||||
|
||||
``HEAD`` represents in git the version you are working on (in working tree).
|
||||
Your ``HEAD`` can be attached (using a reference) or detached (using a commit).
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$head = $repository->getHead(); // Commit or Reference
|
||||
$head = $repository->getHeadCommit(); // Commit
|
||||
|
||||
if ($repository->isHeadDetached()) {
|
||||
echo "Sorry man\n";
|
||||
}
|
||||
|
||||
Options for repository
|
||||
----------------------
|
||||
|
||||
Logger
|
||||
......
|
||||
|
||||
If you are developing, you may appreciate to have a logger inside repository, telling you every executed command.
|
||||
|
||||
You call method ``setLogger`` as an option on repository creation:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$repository->setLogger(new Monolog\Logger('repository'));
|
||||
|
||||
$repository->run('fetch', array('--all'));
|
||||
|
||||
You can also specify as an option on repository creation:
|
||||
|
||||
$logger = new Monolog\Logger('repository');
|
||||
$repository = new Repository('/path/foo', array('logger' => $logger));
|
||||
|
||||
$repository->run('fetch', array('--all'));
|
||||
|
||||
This will output:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
info run command: fetch "--all"
|
||||
debug last command (fetch) duration: 23.24ms
|
||||
debug last command (fetch) return code: 0
|
||||
debug last command (fetch) output: Fetching origin
|
||||
|
||||
Disable debug-mode
|
||||
..................
|
||||
|
||||
Gitlib throws an exception when something seems wrong. If a ``git` command returns a non-zero result, it will stop execution and throw an ``RuntimeException``.
|
||||
|
||||
If you want to prevent this, set ``debug`` option to ``false``. This will make Repository log errors and return empty data instead of throwing exceptions.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$repository = new Repository('/tmp/foo', array('debug' => false, 'logger' => $logger));
|
||||
|
||||
.. note:: if you plan to disable debug, you should rely on logger to keep a trace of edge failing cases.
|
||||
|
||||
Specify git command to use
|
||||
..........................
|
||||
|
||||
You can pass option ``command`` to specify which command to use to run git calls. If you have a git binary
|
||||
located somewhere else, use this option to specify to gitlib path to your git binary:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$repository = new Gitonomy\Git\Repository('/tmp/foo', array('command' => '/home/alice/bin/git'));
|
||||
|
||||
Environment variables
|
||||
.....................
|
||||
|
||||
Now you want to set environment variables to use to run ``git`` commands. It might be useful.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$repository = new Gitonomy\Git\Repository('/tmp/foo', array('environment_variables' => array('GIT_')))
|
28
vendor/gitonomy/gitlib/doc/api/revision.rst
vendored
Normal file
28
vendor/gitonomy/gitlib/doc/api/revision.rst
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
Revision
|
||||
========
|
||||
|
||||
To get a revision from a *Repository* object:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$revision = $repository->getRevision('master@{2 days ago}');
|
||||
|
||||
Getting the log
|
||||
---------------
|
||||
|
||||
You can access a *Log* object starting from a revision using the *getLog*
|
||||
method. This method takes two parameters: *offset* and *limit*:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
// Returns 100 lasts commits
|
||||
$log = $revision->getLog(null, 100);
|
||||
|
||||
Resolve a revision
|
||||
------------------
|
||||
|
||||
To resolve a revision to a commit:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$commit = $revision->getCommit();
|
54
vendor/gitonomy/gitlib/doc/api/tree.rst
vendored
Normal file
54
vendor/gitonomy/gitlib/doc/api/tree.rst
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
Tree and files
|
||||
==============
|
||||
|
||||
To organize folders, git uses trees. In gitlib, those trees are represented
|
||||
via *Tree* object.
|
||||
|
||||
To get the root tree associated to a commit, use the *getTree* method on the
|
||||
commit object:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$tree = $commit->getTree();
|
||||
|
||||
This tree is the entry point of all of your files.
|
||||
|
||||
The main method for a tree is the *getEntries* method. This method will
|
||||
return an array, indexed by name. Each of those elements will be the entry mode
|
||||
and the entry object.
|
||||
|
||||
Let's understand how it works with a concrete example:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
function displayTree(Tree $tree, $indent = 0)
|
||||
{
|
||||
$indent = str_repeat(' ', $indent);
|
||||
foreach ($tree->getEntries() as $name => $data) {
|
||||
list($mode, $entry) = $data;
|
||||
if ($entry instanceof Tree) {
|
||||
echo $indent.$name."/\n";
|
||||
displayTree($tree, $indent + 1);
|
||||
} else {
|
||||
echo $indent.$name."\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
displayTree($commit->getTree());
|
||||
|
||||
This method will recursively display all entries of a tree.
|
||||
|
||||
Resolve a path
|
||||
--------------
|
||||
|
||||
To access directly a sub-file, the easier is probably to use the *resolvePath*
|
||||
method.
|
||||
|
||||
An example:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$source = $tree->resolvePath('src/Gitonomy/Git');
|
||||
|
||||
$source instanceof Tree;
|
45
vendor/gitonomy/gitlib/doc/api/workingcopy.rst
vendored
Normal file
45
vendor/gitonomy/gitlib/doc/api/workingcopy.rst
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
Working copy
|
||||
============
|
||||
|
||||
Working copy is the folder associated to a git repository. In *gitlib*, you
|
||||
can access this object using the *getWorkingCopy* on a *Repository* object:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$repo = new Repository('/path/to/working-dir');
|
||||
$wc = $repo->getWorkingCopy();
|
||||
|
||||
Checkout a revision
|
||||
-------------------
|
||||
|
||||
You can checkout any revision using *checkout* method. You can also pass a
|
||||
second argument, which will be passed as argument with ``-b``:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
// git checkout master
|
||||
$wc->checkout('master');
|
||||
|
||||
// git checkout origin/master -b master
|
||||
$wc->checkout('origin/master', 'master');
|
||||
|
||||
You can also pass a *Reference* or a *Commit*.
|
||||
|
||||
Staged modifications
|
||||
--------------------
|
||||
|
||||
You can get a diff of modifications pending in staging area. To get the ``Diff`` object,
|
||||
call method ``getDiffStaged()``:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$diff = $wc->getDiffStaged();
|
||||
|
||||
Pending modifications
|
||||
---------------------
|
||||
|
||||
You can get pending modifications on tracked files by calling method ``getDiffPending()``:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$diff = $wc->getDiffPending();
|
22
vendor/gitonomy/gitlib/doc/debug.rst
vendored
Normal file
22
vendor/gitonomy/gitlib/doc/debug.rst
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
Debug-mode
|
||||
==========
|
||||
|
||||
gitlib offers a debug mode, to make you see edge-cases of your usage. This is called
|
||||
debug-mode.
|
||||
|
||||
Debug-mode is enabled by default. If you disable it, gitlib will behave differently:
|
||||
|
||||
* when an error is met during execution, gitlib will try to minimize it, to not block
|
||||
execution flow. Errors will still be reporter in logger.
|
||||
* logs will be more verbose. They will contain every output, every return code, every
|
||||
possible information to ease debugging.
|
||||
|
||||
If you want to disable exceptions and try to minimize as much as possible errors, pass
|
||||
``false`` when construction a repository:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$repository = new Gitonomy\Git\Repository($path'/tmp/repo', $debug = false)
|
||||
|
||||
``$debug`` argument should be available in every method you can use to create a
|
||||
repository.
|
24
vendor/gitonomy/gitlib/doc/development.rst
vendored
Normal file
24
vendor/gitonomy/gitlib/doc/development.rst
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
Developing gitlib
|
||||
=================
|
||||
|
||||
If you plan to contribute to gitlib, here are few things you should know:
|
||||
|
||||
Documentation generation
|
||||
::::::::::::::::::::::::
|
||||
|
||||
Documentation is generated using Sphinx (restructured text). Configuration file
|
||||
is located in https://github.com/gitonomy/website/blob/master/bin/conf.py
|
||||
|
||||
You will need to fetch vendor modules for PHP blocks especially. If you really
|
||||
want to generate it, install the website project locally and hack into it.
|
||||
|
||||
Test against different git versions
|
||||
:::::::::::::::::::::::::::::::::::
|
||||
|
||||
A script ``test-git-version.sh`` is available in repository to test gitlib against
|
||||
many git versions.
|
||||
|
||||
This script is not usable on Travis-CI, they would hate me for this. It creates
|
||||
a local cache to avoid fetching from Github and compiling if already compiled.
|
||||
|
||||
Use it at your own risk, it's still under experiment.
|
59
vendor/gitonomy/gitlib/doc/index.rst
vendored
Normal file
59
vendor/gitonomy/gitlib/doc/index.rst
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
gitlib - library to manipulate git
|
||||
==================================
|
||||
|
||||
gitlib requires PHP 5.3 and class autoloading (PSR-0) to work properly. Internally, it relies on ``git`` method calls
|
||||
to fetch informations from repository.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
use Gitonomy\Git\Repository;
|
||||
|
||||
$repository = new Repository('/path/to/repository');
|
||||
|
||||
foreach ($repository->getReferences()->getBranches() as $branch) {
|
||||
echo "- ".$branch->getName();
|
||||
}
|
||||
|
||||
$repository->run('fetch', array('--all'));
|
||||
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
api/admin
|
||||
api/repository
|
||||
api/hooks
|
||||
api/workingcopy
|
||||
api/commit
|
||||
api/blame
|
||||
api/blob
|
||||
api/branch
|
||||
api/tree
|
||||
api/log
|
||||
api/diff
|
||||
api/references
|
||||
api/revision
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
installation
|
||||
debug
|
||||
development
|
||||
|
||||
Missing features
|
||||
----------------
|
||||
|
||||
Some major features are still missing from gitlib:
|
||||
|
||||
* Remotes
|
||||
* Submodules
|
||||
|
||||
If you want to run git commands on repository, call method ``Repository::run`` with method and arguments.
|
20
vendor/gitonomy/gitlib/doc/installation.rst
vendored
Normal file
20
vendor/gitonomy/gitlib/doc/installation.rst
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
Installation of gitlib
|
||||
======================
|
||||
|
||||
Autoloading
|
||||
:::::::::::
|
||||
|
||||
gitlib relies on class autoloading. It does not require any additional setup.
|
||||
|
||||
Using composer
|
||||
::::::::::::::
|
||||
|
||||
Edit your ``composer.json`` file and add ``gitonomy/gitlib`` in section ``require``:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"require": {
|
||||
"gitonomy/gitlib": "^1.0"
|
||||
}
|
||||
}
|
21
vendor/gitonomy/gitlib/phpunit.xml.dist
vendored
Normal file
21
vendor/gitonomy/gitlib/phpunit.xml.dist
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit
|
||||
backupGlobals = "false"
|
||||
backupStaticAttributes = "false"
|
||||
colors = "true"
|
||||
convertErrorsToExceptions = "true"
|
||||
convertNoticesToExceptions = "true"
|
||||
convertWarningsToExceptions = "true"
|
||||
processIsolation = "false"
|
||||
stopOnFailure = "false"
|
||||
syntaxCheck = "false"
|
||||
bootstrap = "tests/bootstrap.php" >
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="Test Suite">
|
||||
<directory>tests/Gitonomy/Git/Tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
</phpunit>
|
173
vendor/gitonomy/gitlib/src/Gitonomy/Git/Admin.php
vendored
Normal file
173
vendor/gitonomy/gitlib/src/Gitonomy/Git/Admin.php
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git;
|
||||
|
||||
use Gitonomy\Git\Exception\RuntimeException;
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
/**
|
||||
* Administration class for Git repositories.
|
||||
*
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*/
|
||||
class Admin
|
||||
{
|
||||
/**
|
||||
* Initializes a repository and returns the instance.
|
||||
*
|
||||
* @param string $path path to the repository
|
||||
* @param bool $bare indicate to create a bare repository
|
||||
* @param array $options options for Repository creation
|
||||
*
|
||||
* @return Repository
|
||||
*
|
||||
* @throws RuntimeException Directory exists or not writable (only if debug=true)
|
||||
*/
|
||||
public static function init($path, $bare = true, array $options = array())
|
||||
{
|
||||
$process = static::getProcess('init', array_merge(array('-q'), $bare ? array('--bare') : array(), array($path)), $options);
|
||||
|
||||
$process->run();
|
||||
|
||||
if (!$process->isSuccessFul()) {
|
||||
throw new RuntimeException(sprintf("Error on repository initialization, command wasn't successful (%s). Error output:\n%s", $process->getCommandLine(), $process->getErrorOutput()));
|
||||
}
|
||||
|
||||
return new Repository($path, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the validity of a git repository url without cloning it.
|
||||
*
|
||||
* This will use the `ls-remote` command of git against the given url.
|
||||
* Usually, this command returns 0 when successful, and 128 when the
|
||||
* repository is not found.
|
||||
*
|
||||
* @param string $url url of repository to check
|
||||
* @param array $options options for Repository creation
|
||||
*
|
||||
* @return bool true if url is valid
|
||||
*/
|
||||
public static function isValidRepository($url, array $options = array())
|
||||
{
|
||||
$process = static::getProcess('ls-remote', array($url), $options);
|
||||
|
||||
$process->run();
|
||||
|
||||
return $process->isSuccessFul();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone a repository to a local path.
|
||||
*
|
||||
* @param string $path indicates where to clone repository
|
||||
* @param string $url url of repository to clone
|
||||
* @param bool $bare indicates if repository should be bare or have a working copy
|
||||
* @param array $options options for Repository creation
|
||||
*
|
||||
* @return Repository
|
||||
*/
|
||||
public static function cloneTo($path, $url, $bare = true, array $options = array())
|
||||
{
|
||||
$args = $bare ? array('--bare') : array();
|
||||
|
||||
return static::cloneRepository($path, $url, $args, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone a repository branch to a local path.
|
||||
*
|
||||
* @param string $path indicates where to clone repository
|
||||
* @param string $url url of repository to clone
|
||||
* @param string $branch branch to clone
|
||||
* @param bool $bare indicates if repository should be bare or have a working copy
|
||||
* @param array $options options for Repository creation
|
||||
*
|
||||
* @return Repository
|
||||
*/
|
||||
public static function cloneBranchTo($path, $url, $branch, $bare = true, $options = array())
|
||||
{
|
||||
$args = array('--branch', $branch);
|
||||
if ($bare) {
|
||||
$args[] = '--bare';
|
||||
}
|
||||
|
||||
return static::cloneRepository($path, $url, $args, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mirrors a repository (fetch all revisions, not only branches).
|
||||
*
|
||||
* @param string $path indicates where to clone repository
|
||||
* @param string $url url of repository to clone
|
||||
* @param array $options options for Repository creation
|
||||
*
|
||||
* @return Repository
|
||||
*/
|
||||
public static function mirrorTo($path, $url, array $options = array())
|
||||
{
|
||||
return static::cloneRepository($path, $url, array('--mirror'), $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to launch effective ``git clone`` command.
|
||||
*
|
||||
* @param string $path indicates where to clone repository
|
||||
* @param string $url url of repository to clone
|
||||
* @param array $args arguments to be added to the command-line
|
||||
* @param array $options options for Repository creation
|
||||
*
|
||||
* @return Repository
|
||||
*/
|
||||
public static function cloneRepository($path, $url, array $args = array(), array $options = array())
|
||||
{
|
||||
$process = static::getProcess('clone', array_merge(array('-q'), $args, array($url, $path)), $options);
|
||||
|
||||
$process->run();
|
||||
|
||||
if (!$process->isSuccessFul()) {
|
||||
throw new RuntimeException(sprintf('Error while initializing repository: %s', $process->getErrorOutput()));
|
||||
}
|
||||
|
||||
return new Repository($path, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* This internal method is used to create a process object.
|
||||
*/
|
||||
private static function getProcess($command, array $args = array(), array $options = array())
|
||||
{
|
||||
$is_windows = defined('PHP_WINDOWS_VERSION_BUILD');
|
||||
$options = array_merge(array(
|
||||
'environment_variables' => $is_windows ? array('PATH' => getenv('PATH')) : array(),
|
||||
'command' => 'git',
|
||||
'process_timeout' => 3600,
|
||||
), $options);
|
||||
|
||||
$commandline = array_merge(array($options['command'], $command), $args);
|
||||
|
||||
// Backward compatible layer for Symfony Process < 4.0.
|
||||
if (class_exists('Symfony\Component\Process\ProcessBuilder')) {
|
||||
$commandline = implode(' ', array_map(
|
||||
'Symfony\Component\Process\ProcessUtils::escapeArgument',
|
||||
$commandline
|
||||
));
|
||||
}
|
||||
|
||||
$process = new Process($commandline);
|
||||
$process->setEnv($options['environment_variables']);
|
||||
$process->setTimeout($options['process_timeout']);
|
||||
$process->setIdleTimeout($options['process_timeout']);
|
||||
|
||||
return $process;
|
||||
}
|
||||
}
|
145
vendor/gitonomy/gitlib/src/Gitonomy/Git/Blame.php
vendored
Normal file
145
vendor/gitonomy/gitlib/src/Gitonomy/Git/Blame.php
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git;
|
||||
|
||||
use Gitonomy\Git\Blame\Line;
|
||||
use Gitonomy\Git\Exception\InvalidArgumentException;
|
||||
use Gitonomy\Git\Parser\BlameParser;
|
||||
|
||||
/**
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*/
|
||||
class Blame implements \Countable
|
||||
{
|
||||
/**
|
||||
* @var Repository
|
||||
*/
|
||||
protected $repository;
|
||||
|
||||
/**
|
||||
* @var Revision
|
||||
*/
|
||||
protected $revision;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $file;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
protected $lineRange;
|
||||
|
||||
/**
|
||||
* @var array|null
|
||||
*/
|
||||
protected $lines;
|
||||
|
||||
/**
|
||||
* @param string $lineRange Argument to pass to git blame (-L).
|
||||
* Can be a line range (40,60 or 40,+21)
|
||||
* or a regexp ('/^function$/')
|
||||
*/
|
||||
public function __construct(Repository $repository, Revision $revision, $file, $lineRange = null)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
$this->revision = $revision;
|
||||
$this->lineRange = $lineRange;
|
||||
$this->file = $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Line
|
||||
*/
|
||||
public function getLine($number)
|
||||
{
|
||||
if ($number < 1) {
|
||||
throw new InvalidArgumentException('Line number should be at least 1');
|
||||
}
|
||||
|
||||
$lines = $this->getLines();
|
||||
|
||||
if (!isset($lines[$number])) {
|
||||
throw new InvalidArgumentException('Line does not exist');
|
||||
}
|
||||
|
||||
return $lines[$number];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns lines grouped by commit.
|
||||
*
|
||||
* @return array a list of two-elements array (commit, lines)
|
||||
*/
|
||||
public function getGroupedLines()
|
||||
{
|
||||
$result = array();
|
||||
$commit = null;
|
||||
$current = array();
|
||||
|
||||
foreach ($this->getLines() as $lineNumber => $line) {
|
||||
if ($commit !== $line->getCommit()) {
|
||||
if (count($current)) {
|
||||
$result[] = array($commit, $current);
|
||||
}
|
||||
$commit = $line->getCommit();
|
||||
$current = array();
|
||||
}
|
||||
|
||||
$current[$lineNumber] = $line;
|
||||
}
|
||||
|
||||
if (count($current)) {
|
||||
$result[] = array($commit, $current);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all lines of the blame.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLines()
|
||||
{
|
||||
if (null !== $this->lines) {
|
||||
return $this->lines;
|
||||
}
|
||||
|
||||
$args = array('-p');
|
||||
|
||||
if (null !== $this->lineRange) {
|
||||
$args[] = '-L';
|
||||
$args[] = $this->lineRange;
|
||||
}
|
||||
|
||||
$args[] = $this->revision->getRevision();
|
||||
$args[] = '--';
|
||||
$args[] = $this->file;
|
||||
|
||||
$parser = new BlameParser($this->repository);
|
||||
$parser->parse($this->repository->run('blame', $args));
|
||||
$this->lines = $parser->lines;
|
||||
|
||||
return $this->lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->getLines());
|
||||
}
|
||||
}
|
56
vendor/gitonomy/gitlib/src/Gitonomy/Git/Blame/Line.php
vendored
Normal file
56
vendor/gitonomy/gitlib/src/Gitonomy/Git/Blame/Line.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Blame;
|
||||
|
||||
use Gitonomy\Git\Commit;
|
||||
|
||||
/**
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*/
|
||||
class Line
|
||||
{
|
||||
/**
|
||||
* @var Commit
|
||||
*/
|
||||
protected $commit;
|
||||
protected $sourceLine;
|
||||
protected $targetLine;
|
||||
protected $blockLine;
|
||||
protected $content;
|
||||
|
||||
/**
|
||||
* Instanciates a new Line object.
|
||||
*/
|
||||
public function __construct(Commit $commit, $sourceLine, $targetLine, $blockLine, $content)
|
||||
{
|
||||
$this->commit = $commit;
|
||||
$this->sourceLine = $sourceLine;
|
||||
$this->targetLine = $targetLine;
|
||||
$this->blockLine = $blockLine;
|
||||
$this->content = $content;
|
||||
}
|
||||
|
||||
public function getContent()
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
public function getLine()
|
||||
{
|
||||
return $this->sourceLine;
|
||||
}
|
||||
|
||||
public function getCommit()
|
||||
{
|
||||
return $this->commit;
|
||||
}
|
||||
}
|
107
vendor/gitonomy/gitlib/src/Gitonomy/Git/Blob.php
vendored
Normal file
107
vendor/gitonomy/gitlib/src/Gitonomy/Git/Blob.php
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git;
|
||||
|
||||
/**
|
||||
* Representation of a Blob commit.
|
||||
*
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*/
|
||||
class Blob
|
||||
{
|
||||
/**
|
||||
* @var Repository
|
||||
*/
|
||||
protected $repository;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $hash;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $content;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $mimetype;
|
||||
|
||||
/**
|
||||
* @param Repository $repository Repository where the blob is located
|
||||
* @param string $hash Hash of the blob
|
||||
*/
|
||||
public function __construct(Repository $repository, $hash)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
$this->hash = $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHash()
|
||||
{
|
||||
return $this->hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns content of the blob.
|
||||
*
|
||||
* @throws ProcessException Error occurred while getting content of blob
|
||||
*/
|
||||
public function getContent()
|
||||
{
|
||||
if (null === $this->content) {
|
||||
$this->content = $this->repository->run('cat-file', array('-p', $this->hash));
|
||||
}
|
||||
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the mimetype of the blob.
|
||||
*
|
||||
* @return string A mimetype
|
||||
*/
|
||||
public function getMimetype()
|
||||
{
|
||||
if (null === $this->mimetype) {
|
||||
$finfo = new \finfo(FILEINFO_MIME);
|
||||
$this->mimetype = $finfo->buffer($this->getContent());
|
||||
}
|
||||
|
||||
return $this->mimetype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if file is binary.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isBinary()
|
||||
{
|
||||
return !$this->isText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if file is text.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isText()
|
||||
{
|
||||
return (bool) preg_match('#^text/|^application/xml#', $this->getMimetype());
|
||||
}
|
||||
}
|
404
vendor/gitonomy/gitlib/src/Gitonomy/Git/Commit.php
vendored
Normal file
404
vendor/gitonomy/gitlib/src/Gitonomy/Git/Commit.php
vendored
Normal file
@@ -0,0 +1,404 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git;
|
||||
|
||||
use Gitonomy\Git\Diff\Diff;
|
||||
use Gitonomy\Git\Exception\InvalidArgumentException;
|
||||
use Gitonomy\Git\Exception\ProcessException;
|
||||
use Gitonomy\Git\Exception\ReferenceNotFoundException;
|
||||
use Gitonomy\Git\Util\StringHelper;
|
||||
|
||||
/**
|
||||
* Representation of a Git commit.
|
||||
*
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*/
|
||||
class Commit extends Revision
|
||||
{
|
||||
/**
|
||||
* Associative array of commit data.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $data = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Gitonomy\Git\Repository $repository Repository of the commit
|
||||
* @param string $hash Hash of the commit
|
||||
*/
|
||||
public function __construct(Repository $repository, $hash, array $data = array())
|
||||
{
|
||||
if (!preg_match('/^[a-f0-9]{40}$/', $hash)) {
|
||||
throw new ReferenceNotFoundException($hash);
|
||||
}
|
||||
|
||||
parent::__construct($repository, $hash);
|
||||
|
||||
$this->setData($data);
|
||||
}
|
||||
|
||||
public function setData(array $data)
|
||||
{
|
||||
foreach ($data as $name => $value) {
|
||||
$this->data[$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Diff
|
||||
*/
|
||||
public function getDiff()
|
||||
{
|
||||
$args = array('-r', '-p', '-m', '-M', '--no-commit-id', '--full-index', $this->revision);
|
||||
|
||||
$diff = Diff::parse($this->repository->run('diff-tree', $args));
|
||||
$diff->setRepository($this->repository);
|
||||
|
||||
return $diff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the commit hash.
|
||||
*
|
||||
* @return string A SHA1 hash
|
||||
*/
|
||||
public function getHash()
|
||||
{
|
||||
return $this->revision;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the short commit hash.
|
||||
*
|
||||
* @return string A SHA1 hash
|
||||
*/
|
||||
public function getShortHash()
|
||||
{
|
||||
return $this->getData('shortHash');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a fixed-with short hash.
|
||||
*/
|
||||
public function getFixedShortHash($length = 6)
|
||||
{
|
||||
return StringHelper::substr($this->revision, 0, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns parent hashes.
|
||||
*
|
||||
* @return array An array of SHA1 hashes
|
||||
*/
|
||||
public function getParentHashes()
|
||||
{
|
||||
return $this->getData('parentHashes');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent commits.
|
||||
*
|
||||
* @return array An array of Commit objects
|
||||
*/
|
||||
public function getParents()
|
||||
{
|
||||
$result = array();
|
||||
foreach ($this->getData('parentHashes') as $parentHash) {
|
||||
$result[] = $this->repository->getCommit($parentHash);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tree hash.
|
||||
*
|
||||
* @return string A SHA1 hash
|
||||
*/
|
||||
public function getTreeHash()
|
||||
{
|
||||
return $this->getData('treeHash');
|
||||
}
|
||||
|
||||
public function getTree()
|
||||
{
|
||||
return $this->getData('tree');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Commit
|
||||
*/
|
||||
public function getLastModification($path = null)
|
||||
{
|
||||
if (0 === strpos($path, '/')) {
|
||||
$path = StringHelper::substr($path, 1);
|
||||
}
|
||||
|
||||
if ($getWorkingDir = $this->repository->getWorkingDir()) {
|
||||
$path = $getWorkingDir.'/'.$path;
|
||||
}
|
||||
|
||||
$result = $this->repository->run('log', array('--format=%H', '-n', 1, $this->revision, '--', $path));
|
||||
|
||||
return $this->repository->getCommit(trim($result));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first line of the commit, and the first 50 characters.
|
||||
*
|
||||
* Ported from https://github.com/fabpot/Twig-extensions/blob/d67bc7e69788795d7905b52d31188bbc1d390e01/lib/Twig/Extensions/Extension/Text.php#L52-L109
|
||||
*
|
||||
* @param int $length
|
||||
* @param bool $preserve
|
||||
* @param string $separator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getShortMessage($length = 50, $preserve = false, $separator = '...')
|
||||
{
|
||||
$message = $this->getData('subjectMessage');
|
||||
|
||||
if (StringHelper::strlen($message) > $length) {
|
||||
if ($preserve && false !== ($breakpoint = StringHelper::strpos($message, ' ', $length))) {
|
||||
$length = $breakpoint;
|
||||
}
|
||||
|
||||
return rtrim(StringHelper::substr($message, 0, $length)).$separator;
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves all references associated to this commit.
|
||||
*
|
||||
* @return array An array of references (Branch, Tag, Squash)
|
||||
*/
|
||||
public function resolveReferences()
|
||||
{
|
||||
return $this->repository->getReferences()->resolve($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find branch containing the commit.
|
||||
*
|
||||
* @param bool $local set true to try to locate a commit on local repository
|
||||
* @param bool $remote set true to try to locate a commit on remote repository
|
||||
*
|
||||
* @return array An array of Reference\Branch
|
||||
*/
|
||||
public function getIncludingBranches($local = true, $remote = true)
|
||||
{
|
||||
$arguments = array('--contains', $this->revision);
|
||||
|
||||
if ($local && $remote) {
|
||||
$arguments[] = '-a';
|
||||
} elseif (!$local && $remote) {
|
||||
$arguments[] = '-r';
|
||||
} elseif (!$local && !$remote) {
|
||||
throw new InvalidArgumentException('You should a least set one argument to true');
|
||||
}
|
||||
|
||||
try {
|
||||
$result = $this->repository->run('branch', $arguments);
|
||||
} catch (ProcessException $e) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if (!$result) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$branchesName = explode("\n", trim(str_replace('*', '', $result)));
|
||||
$branchesName = array_filter($branchesName, function ($v) { return false === StringHelper::strpos($v, '->');});
|
||||
$branchesName = array_map('trim', $branchesName);
|
||||
|
||||
$references = $this->repository->getReferences();
|
||||
|
||||
$branches = array();
|
||||
foreach ($branchesName as $branchName) {
|
||||
if (false === $local) {
|
||||
$branches[] = $references->getRemoteBranch($branchName);
|
||||
} elseif (0 === StringHelper::strrpos($branchName, 'remotes/')) {
|
||||
$branches[] = $references->getRemoteBranch(str_replace('remotes/', '', $branchName));
|
||||
} else {
|
||||
$branches[] = $references->getBranch($branchName);
|
||||
}
|
||||
}
|
||||
|
||||
return $branches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the author name.
|
||||
*
|
||||
* @return string A name
|
||||
*/
|
||||
public function getAuthorName()
|
||||
{
|
||||
return $this->getData('authorName');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the author email.
|
||||
*
|
||||
* @return string An email
|
||||
*/
|
||||
public function getAuthorEmail()
|
||||
{
|
||||
return $this->getData('authorEmail');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the authoring date.
|
||||
*
|
||||
* @return DateTime A time object
|
||||
*/
|
||||
public function getAuthorDate()
|
||||
{
|
||||
return $this->getData('authorDate');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the committer name.
|
||||
*
|
||||
* @return string A name
|
||||
*/
|
||||
public function getCommitterName()
|
||||
{
|
||||
return $this->getData('committerName');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the comitter email.
|
||||
*
|
||||
* @return string An email
|
||||
*/
|
||||
public function getCommitterEmail()
|
||||
{
|
||||
return $this->getData('committerEmail');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the authoring date.
|
||||
*
|
||||
* @return DateTime A time object
|
||||
*/
|
||||
public function getCommitterDate()
|
||||
{
|
||||
return $this->getData('committerDate');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message of the commit.
|
||||
*
|
||||
* @return string A commit message
|
||||
*/
|
||||
public function getMessage()
|
||||
{
|
||||
return $this->getData('message');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the subject message (the first line).
|
||||
*
|
||||
* @return string The subject message
|
||||
*/
|
||||
public function getSubjectMessage()
|
||||
{
|
||||
return $this->getData('subjectMessage');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the body message.
|
||||
*
|
||||
* @return string The body message
|
||||
*/
|
||||
public function getBodyMessage()
|
||||
{
|
||||
return $this->getData('bodyMessage');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getCommit()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function getData($name)
|
||||
{
|
||||
if (isset($this->data[$name])) {
|
||||
return $this->data[$name];
|
||||
}
|
||||
|
||||
if ($name === 'shortHash') {
|
||||
$this->data['shortHash'] = trim($this->repository->run('log', array('--abbrev-commit', '--format=%h', '-n', 1, $this->revision)));
|
||||
|
||||
return $this->data['shortHash'];
|
||||
}
|
||||
|
||||
if ($name === 'tree') {
|
||||
$this->data['tree'] = $this->repository->getTree($this->getData('treeHash'));
|
||||
|
||||
return $this->data['tree'];
|
||||
}
|
||||
|
||||
if ($name === 'subjectMessage') {
|
||||
$lines = explode("\n", $this->getData('message'));
|
||||
$this->data['subjectMessage'] = reset($lines);
|
||||
|
||||
return $this->data['subjectMessage'];
|
||||
}
|
||||
|
||||
if ($name === 'bodyMessage') {
|
||||
$message = $this->getData('message');
|
||||
|
||||
$lines = explode("\n", $message);
|
||||
|
||||
array_shift($lines);
|
||||
array_shift($lines);
|
||||
|
||||
$data['bodyMessage'] = implode("\n", $lines);
|
||||
|
||||
return $data['bodyMessage'];
|
||||
}
|
||||
|
||||
$parser = new Parser\CommitParser();
|
||||
try {
|
||||
$result = $this->repository->run('cat-file', array('commit', $this->revision));
|
||||
} catch (ProcessException $e) {
|
||||
throw new ReferenceNotFoundException(sprintf('Can not find reference "%s"', $this->revision));
|
||||
}
|
||||
|
||||
$parser->parse($result);
|
||||
|
||||
$this->data['treeHash'] = $parser->tree;
|
||||
$this->data['parentHashes'] = $parser->parents;
|
||||
$this->data['authorName'] = $parser->authorName;
|
||||
$this->data['authorEmail'] = $parser->authorEmail;
|
||||
$this->data['authorDate'] = $parser->authorDate;
|
||||
$this->data['committerName'] = $parser->committerName;
|
||||
$this->data['committerEmail'] = $parser->committerEmail;
|
||||
$this->data['committerDate'] = $parser->committerDate;
|
||||
$this->data['message'] = $parser->message;
|
||||
|
||||
if (!isset($this->data[$name])) {
|
||||
throw new \InvalidArgumentException(sprintf('No data named "%s" in Commit.', $name));
|
||||
}
|
||||
|
||||
return $this->data[$name];
|
||||
}
|
||||
}
|
22
vendor/gitonomy/gitlib/src/Gitonomy/Git/CommitReference.php
vendored
Normal file
22
vendor/gitonomy/gitlib/src/Gitonomy/Git/CommitReference.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git;
|
||||
|
||||
class CommitReference
|
||||
{
|
||||
private $hash;
|
||||
|
||||
public function __construct($hash)
|
||||
{
|
||||
$this->hash = $hash;
|
||||
}
|
||||
}
|
127
vendor/gitonomy/gitlib/src/Gitonomy/Git/Diff/Diff.php
vendored
Normal file
127
vendor/gitonomy/gitlib/src/Gitonomy/Git/Diff/Diff.php
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Diff;
|
||||
|
||||
use Gitonomy\Git\Parser\DiffParser;
|
||||
use Gitonomy\Git\Repository;
|
||||
|
||||
/**
|
||||
* Representation of a diff.
|
||||
*
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*/
|
||||
class Diff
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $files;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $rawDiff;
|
||||
|
||||
/**
|
||||
* Constructs a new diff for a given revision.
|
||||
*
|
||||
* @param array $files The files
|
||||
* @param string $rawDiff The raw diff
|
||||
*/
|
||||
public function __construct(array $files, $rawDiff)
|
||||
{
|
||||
$this->files = $files;
|
||||
$this->rawDiff = $rawDiff;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Diff
|
||||
*/
|
||||
public static function parse($rawDiff)
|
||||
{
|
||||
$parser = new DiffParser();
|
||||
$parser->parse($rawDiff);
|
||||
|
||||
return new self($parser->files, $rawDiff);
|
||||
}
|
||||
|
||||
public function setRepository(Repository $repository)
|
||||
{
|
||||
foreach ($this->files as $file) {
|
||||
$file->setRepository($repository);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getRevisions()
|
||||
{
|
||||
return $this->revisions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of files modified in the diff's revision.
|
||||
*
|
||||
* @return array An array of Diff\File objects
|
||||
*/
|
||||
public function getFiles()
|
||||
{
|
||||
return $this->files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw diff.
|
||||
*
|
||||
* @return string The raw diff
|
||||
*/
|
||||
public function getRawDiff()
|
||||
{
|
||||
return $this->rawDiff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export a diff as array.
|
||||
*
|
||||
* @return array The array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return array(
|
||||
'rawDiff' => $this->rawDiff,
|
||||
'files' => array_map(
|
||||
function (File $file) {
|
||||
return $file->toArray();
|
||||
}, $this->files
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of Diff from an array.
|
||||
*
|
||||
* @param array $array The array
|
||||
*
|
||||
* @return Diff The new instance
|
||||
*/
|
||||
public static function fromArray(array $array)
|
||||
{
|
||||
return new static(
|
||||
array_map(
|
||||
function ($array) {
|
||||
return File::fromArray($array);
|
||||
}, $array['files']
|
||||
),
|
||||
$array['rawDiff']
|
||||
);
|
||||
}
|
||||
}
|
289
vendor/gitonomy/gitlib/src/Gitonomy/Git/Diff/File.php
vendored
Normal file
289
vendor/gitonomy/gitlib/src/Gitonomy/Git/Diff/File.php
vendored
Normal file
@@ -0,0 +1,289 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Diff;
|
||||
|
||||
use Gitonomy\Git\Repository;
|
||||
|
||||
/**
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*/
|
||||
class File
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $oldName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $newName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $oldMode;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $newMode;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $oldIndex;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $newIndex;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $isBinary;
|
||||
|
||||
/**
|
||||
* @var array An array of FileChange objects
|
||||
*/
|
||||
protected $changes;
|
||||
|
||||
/**
|
||||
* @var Repository
|
||||
*/
|
||||
protected $repository;
|
||||
|
||||
/**
|
||||
* Instanciates a new File object.
|
||||
*/
|
||||
public function __construct($oldName, $newName, $oldMode, $newMode, $oldIndex, $newIndex, $isBinary)
|
||||
{
|
||||
$this->oldName = $oldName;
|
||||
$this->newName = $newName;
|
||||
$this->oldMode = $oldMode;
|
||||
$this->newMode = $newMode;
|
||||
$this->oldIndex = $oldIndex;
|
||||
$this->newIndex = $newIndex;
|
||||
$this->isBinary = $isBinary;
|
||||
|
||||
$this->changes = array();
|
||||
}
|
||||
|
||||
public function addChange(FileChange $change)
|
||||
{
|
||||
$this->changes[] = $change;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this diff file is a creation.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isCreation()
|
||||
{
|
||||
return null === $this->oldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this diff file is a modification.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isModification()
|
||||
{
|
||||
return null !== $this->oldName && null !== $this->newName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if it's a rename.
|
||||
*
|
||||
* A rename can only occurs if it's a modification (not a creation or a deletion).
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isRename()
|
||||
{
|
||||
return $this->isModification() && $this->oldName !== $this->newName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if the file mode has changed.
|
||||
*/
|
||||
public function isChangeMode()
|
||||
{
|
||||
return $this->isModification() && $this->oldMode !== $this->newMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this diff file is a deletion.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDeletion()
|
||||
{
|
||||
return null === $this->newName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this diff file is a deletion.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDelete()
|
||||
{
|
||||
return null === $this->newName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int Number of added lines
|
||||
*/
|
||||
public function getAdditions()
|
||||
{
|
||||
$result = 0;
|
||||
foreach ($this->changes as $change) {
|
||||
$result += $change->getCount(FileChange::LINE_ADD);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int Number of deleted lines
|
||||
*/
|
||||
public function getDeletions()
|
||||
{
|
||||
$result = 0;
|
||||
foreach ($this->changes as $change) {
|
||||
$result += $change->getCount(FileChange::LINE_REMOVE);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getOldName()
|
||||
{
|
||||
return $this->oldName;
|
||||
}
|
||||
|
||||
public function getNewName()
|
||||
{
|
||||
return $this->newName;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
if (null === $this->newName) {
|
||||
return $this->oldName;
|
||||
}
|
||||
|
||||
return $this->newName;
|
||||
}
|
||||
|
||||
public function getOldMode()
|
||||
{
|
||||
return $this->oldMode;
|
||||
}
|
||||
|
||||
public function getNewMode()
|
||||
{
|
||||
return $this->newMode;
|
||||
}
|
||||
|
||||
public function getOldIndex()
|
||||
{
|
||||
return $this->oldIndex;
|
||||
}
|
||||
|
||||
public function getNewIndex()
|
||||
{
|
||||
return $this->newIndex;
|
||||
}
|
||||
|
||||
public function isBinary()
|
||||
{
|
||||
return $this->isBinary;
|
||||
}
|
||||
|
||||
public function getChanges()
|
||||
{
|
||||
return $this->changes;
|
||||
}
|
||||
|
||||
public function toArray()
|
||||
{
|
||||
return array(
|
||||
'old_name' => $this->oldName,
|
||||
'new_name' => $this->newName,
|
||||
'old_mode' => $this->oldMode,
|
||||
'new_mode' => $this->newMode,
|
||||
'old_index' => $this->oldIndex,
|
||||
'new_index' => $this->newIndex,
|
||||
'is_binary' => $this->isBinary,
|
||||
'changes' => array_map(function (FileChange $change) {
|
||||
return $change->toArray();
|
||||
}, $this->changes),
|
||||
);
|
||||
}
|
||||
|
||||
public static function fromArray(array $array)
|
||||
{
|
||||
$file = new self($array['old_name'], $array['new_name'], $array['old_mode'], $array['new_mode'], $array['old_index'], $array['new_index'], $array['is_binary']);
|
||||
|
||||
foreach ($array['changes'] as $change) {
|
||||
$file->addChange(FileChange::fromArray($change));
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
public function getAnchor()
|
||||
{
|
||||
return substr($this->newIndex, 0, 12);
|
||||
}
|
||||
|
||||
public function getRepository()
|
||||
{
|
||||
return $this->repository;
|
||||
}
|
||||
|
||||
public function setRepository(Repository $repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
public function getOldBlob()
|
||||
{
|
||||
if (null === $this->repository) {
|
||||
throw new \RuntimeException('Repository is missing to return Blob object.');
|
||||
}
|
||||
|
||||
if ($this->isCreation()) {
|
||||
throw new \LogicException('Can\'t return old Blob on a creation');
|
||||
}
|
||||
|
||||
return $this->repository->getBlob($this->oldIndex);
|
||||
}
|
||||
|
||||
public function getNewBlob()
|
||||
{
|
||||
if (null === $this->repository) {
|
||||
throw new \RuntimeException('Repository is missing to return Blob object.');
|
||||
}
|
||||
|
||||
if ($this->isDeletion()) {
|
||||
throw new \LogicException('Can\'t return new Blob on a deletion');
|
||||
}
|
||||
|
||||
return $this->repository->getBlob($this->newIndex);
|
||||
}
|
||||
}
|
87
vendor/gitonomy/gitlib/src/Gitonomy/Git/Diff/FileChange.php
vendored
Normal file
87
vendor/gitonomy/gitlib/src/Gitonomy/Git/Diff/FileChange.php
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Diff;
|
||||
|
||||
class FileChange
|
||||
{
|
||||
const LINE_CONTEXT = 0;
|
||||
const LINE_REMOVE = -1;
|
||||
const LINE_ADD = 1;
|
||||
|
||||
protected $rangeOldStart;
|
||||
protected $rangeOldCount;
|
||||
protected $rangeNewStart;
|
||||
protected $rangeNewCount;
|
||||
protected $lines;
|
||||
|
||||
public function __construct($rangeOldStart, $rangeOldCount, $rangeNewStart, $rangeNewCount, $lines)
|
||||
{
|
||||
$this->rangeOldStart = $rangeOldStart;
|
||||
$this->rangeOldCount = $rangeOldCount;
|
||||
$this->rangeNewStart = $rangeNewStart;
|
||||
$this->rangeNewCount = $rangeNewCount;
|
||||
$this->lines = $lines;
|
||||
}
|
||||
|
||||
public function getCount($type)
|
||||
{
|
||||
$result = 0;
|
||||
foreach ($this->lines as $line) {
|
||||
if ($line[0] === $type) {
|
||||
++$result;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getRangeOldStart()
|
||||
{
|
||||
return $this->rangeOldStart;
|
||||
}
|
||||
|
||||
public function getRangeOldCount()
|
||||
{
|
||||
return $this->rangeOldCount;
|
||||
}
|
||||
|
||||
public function getRangeNewStart()
|
||||
{
|
||||
return $this->rangeNewStart;
|
||||
}
|
||||
|
||||
public function getRangeNewCount()
|
||||
{
|
||||
return $this->rangeNewCount;
|
||||
}
|
||||
|
||||
public function getLines()
|
||||
{
|
||||
return $this->lines;
|
||||
}
|
||||
|
||||
public function toArray()
|
||||
{
|
||||
return array(
|
||||
'range_old_start' => $this->rangeOldStart,
|
||||
'range_old_count' => $this->rangeOldCount,
|
||||
'range_new_start' => $this->rangeNewStart,
|
||||
'range_new_count' => $this->rangeNewCount,
|
||||
'lines' => $this->lines,
|
||||
);
|
||||
}
|
||||
|
||||
public static function fromArray(array $array)
|
||||
{
|
||||
return new self($array['range_old_start'], $array['range_old_count'], $array['range_new_start'], $array['range_new_count'], $array['lines']);
|
||||
}
|
||||
}
|
16
vendor/gitonomy/gitlib/src/Gitonomy/Git/Exception/GitExceptionInterface.php
vendored
Normal file
16
vendor/gitonomy/gitlib/src/Gitonomy/Git/Exception/GitExceptionInterface.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Exception;
|
||||
|
||||
interface GitExceptionInterface
|
||||
{
|
||||
}
|
7
vendor/gitonomy/gitlib/src/Gitonomy/Git/Exception/InvalidArgumentException.php
vendored
Normal file
7
vendor/gitonomy/gitlib/src/Gitonomy/Git/Exception/InvalidArgumentException.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Gitonomy\Git\Exception;
|
||||
|
||||
class InvalidArgumentException extends \InvalidArgumentException implements GitExceptionInterface
|
||||
{
|
||||
}
|
7
vendor/gitonomy/gitlib/src/Gitonomy/Git/Exception/LogicException.php
vendored
Normal file
7
vendor/gitonomy/gitlib/src/Gitonomy/Git/Exception/LogicException.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Gitonomy\Git\Exception;
|
||||
|
||||
class LogicException extends \LogicException implements GitExceptionInterface
|
||||
{
|
||||
}
|
33
vendor/gitonomy/gitlib/src/Gitonomy/Git/Exception/ProcessException.php
vendored
Normal file
33
vendor/gitonomy/gitlib/src/Gitonomy/Git/Exception/ProcessException.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Gitonomy\Git\Exception;
|
||||
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
class ProcessException extends RuntimeException implements GitExceptionInterface
|
||||
{
|
||||
protected $process;
|
||||
|
||||
public function __construct(Process $process)
|
||||
{
|
||||
parent::__construct("Error while running git command:\n".
|
||||
$process->getCommandLine()."\n".
|
||||
"\n".
|
||||
$process->getErrorOutput()."\n".
|
||||
"\n".
|
||||
$process->getOutput()
|
||||
);
|
||||
|
||||
$this->process = $process;
|
||||
}
|
||||
|
||||
public function getErrorOutput()
|
||||
{
|
||||
return $this->process->getErrorOutput();
|
||||
}
|
||||
|
||||
public function getOutput()
|
||||
{
|
||||
return $this->process->getOutput();
|
||||
}
|
||||
}
|
20
vendor/gitonomy/gitlib/src/Gitonomy/Git/Exception/ReferenceNotFoundException.php
vendored
Normal file
20
vendor/gitonomy/gitlib/src/Gitonomy/Git/Exception/ReferenceNotFoundException.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Exception;
|
||||
|
||||
class ReferenceNotFoundException extends \InvalidArgumentException implements GitExceptionInterface
|
||||
{
|
||||
public function __construct($reference)
|
||||
{
|
||||
parent::__construct(sprintf('Reference not found: "%s"', $reference));
|
||||
}
|
||||
}
|
7
vendor/gitonomy/gitlib/src/Gitonomy/Git/Exception/RuntimeException.php
vendored
Normal file
7
vendor/gitonomy/gitlib/src/Gitonomy/Git/Exception/RuntimeException.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Gitonomy\Git\Exception;
|
||||
|
||||
class RuntimeException extends \RuntimeException implements GitExceptionInterface
|
||||
{
|
||||
}
|
7
vendor/gitonomy/gitlib/src/Gitonomy/Git/Exception/UnexpectedValueException.php
vendored
Normal file
7
vendor/gitonomy/gitlib/src/Gitonomy/Git/Exception/UnexpectedValueException.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Gitonomy\Git\Exception;
|
||||
|
||||
class UnexpectedValueException extends \UnexpectedValueException implements GitExceptionInterface
|
||||
{
|
||||
}
|
127
vendor/gitonomy/gitlib/src/Gitonomy/Git/Hooks.php
vendored
Normal file
127
vendor/gitonomy/gitlib/src/Gitonomy/Git/Hooks.php
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git;
|
||||
|
||||
use Gitonomy\Git\Exception\InvalidArgumentException;
|
||||
use Gitonomy\Git\Exception\LogicException;
|
||||
|
||||
/**
|
||||
* Hooks collection, aggregated by repository.
|
||||
*
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*/
|
||||
class Hooks
|
||||
{
|
||||
/**
|
||||
* @var Gitonomy\Git\Repository
|
||||
*/
|
||||
protected $repository;
|
||||
|
||||
/**
|
||||
* @var Repository
|
||||
*/
|
||||
public function __construct(Repository $repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if repository has a given hook.
|
||||
*
|
||||
* @param string $name Name of the hook
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($name)
|
||||
{
|
||||
return file_exists($this->getPath($name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches content of a hook.
|
||||
*
|
||||
* @param string $name Name of the hook
|
||||
*
|
||||
* @return string Content of the hook
|
||||
*
|
||||
* @throws InvalidArgumentException Hook does not exist
|
||||
*/
|
||||
public function get($name)
|
||||
{
|
||||
if (!$this->has($name)) {
|
||||
throw new InvalidArgumentException(sprintf('Hook named "%s" is not present', $name));
|
||||
}
|
||||
|
||||
return file_get_contents($this->getPath($name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a hook in repository using a symlink.
|
||||
*
|
||||
* @param string $name Name of the hook to insert
|
||||
* @param string $file Target of symlink
|
||||
*
|
||||
* @throws LogicException Hook is already present
|
||||
* @throws RuntimeException Error on symlink creation
|
||||
*/
|
||||
public function setSymlink($name, $file)
|
||||
{
|
||||
if ($this->has($name)) {
|
||||
throw new LogicException(sprintf('A hook "%s" is already defined', $name));
|
||||
}
|
||||
|
||||
$path = $this->getPath($name);
|
||||
if (false === symlink($file, $path)) {
|
||||
throw new RuntimeException(sprintf('Unable to create hook "%s"', $name, $path));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a hook in repository.
|
||||
*
|
||||
* @param string $name Name of the hook
|
||||
* @param string $content Content of the hook
|
||||
*
|
||||
* @throws LogicException The hook is already defined
|
||||
*/
|
||||
public function set($name, $content)
|
||||
{
|
||||
if ($this->has($name)) {
|
||||
throw new LogicException(sprintf('A hook "%s" is already defined', $name));
|
||||
}
|
||||
|
||||
$path = $this->getPath($name);
|
||||
file_put_contents($path, $content);
|
||||
chmod($path, 0777);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a hook from repository.
|
||||
*
|
||||
* @param string $name Name of the hook
|
||||
*
|
||||
* @throws LogicException The hook is not present
|
||||
*/
|
||||
public function remove($name)
|
||||
{
|
||||
if (!$this->has($name)) {
|
||||
throw new LogicException(sprintf('The hook "%s" was not found', $name));
|
||||
}
|
||||
|
||||
unlink($this->getPath($name));
|
||||
}
|
||||
|
||||
protected function getPath($name)
|
||||
{
|
||||
return $this->repository->getGitDir().'/hooks/'.$name;
|
||||
}
|
||||
}
|
232
vendor/gitonomy/gitlib/src/Gitonomy/Git/Log.php
vendored
Normal file
232
vendor/gitonomy/gitlib/src/Gitonomy/Git/Log.php
vendored
Normal file
@@ -0,0 +1,232 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git;
|
||||
|
||||
use Gitonomy\Git\Exception\ProcessException;
|
||||
use Gitonomy\Git\Exception\ReferenceNotFoundException;
|
||||
use Gitonomy\Git\Util\StringHelper;
|
||||
|
||||
/**
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*/
|
||||
class Log implements \Countable, \IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* @var Repository
|
||||
*/
|
||||
protected $repository;
|
||||
|
||||
/**
|
||||
* @var null|RevisionList
|
||||
*/
|
||||
protected $revisions;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $paths;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $offset;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $limit;
|
||||
|
||||
/**
|
||||
* Instanciates a git log object.
|
||||
*
|
||||
* @param Repository $repository the repository where log occurs
|
||||
* @param RevisionList|Revision|array|null $revisions a list of revisions or null if you want all history
|
||||
* @param array $paths paths to filter on
|
||||
* @param int|null $offset start list from a given position
|
||||
* @param int|null $limit limit number of fetched elements
|
||||
*/
|
||||
public function __construct(Repository $repository, $revisions = null, $paths = null, $offset = null, $limit = null)
|
||||
{
|
||||
if (null !== $revisions && !$revisions instanceof RevisionList) {
|
||||
$revisions = new RevisionList($repository, $revisions);
|
||||
}
|
||||
|
||||
if (null === $paths) {
|
||||
$paths = array();
|
||||
} elseif (is_string($paths)) {
|
||||
$paths = array($paths);
|
||||
} elseif (!is_array($paths)) {
|
||||
throw new \InvalidArgumentException(sprintf('Expected a string or an array, got a "%s".', is_object($paths) ? get_class($paths) : gettype($paths)));
|
||||
}
|
||||
|
||||
$this->repository = $repository;
|
||||
$this->revisions = $revisions;
|
||||
$this->paths = $paths;
|
||||
$this->offset = $offset;
|
||||
$this->limit = $limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Diff
|
||||
*/
|
||||
public function getDiff()
|
||||
{
|
||||
return $this->repository->getDiff($this->revisions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return RevisionList
|
||||
*/
|
||||
public function getRevisions()
|
||||
{
|
||||
return $this->revisions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPaths()
|
||||
{
|
||||
return $this->paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getOffset()
|
||||
{
|
||||
return $this->offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
*/
|
||||
public function setOffset($offset)
|
||||
{
|
||||
$this->offset = $offset;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getLimit()
|
||||
{
|
||||
return $this->limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $limit
|
||||
*/
|
||||
public function setLimit($limit)
|
||||
{
|
||||
$this->limit = $limit;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSingleCommit()
|
||||
{
|
||||
$limit = $this->limit;
|
||||
$this->limit = 1;
|
||||
$commits = $this->getCommits();
|
||||
$this->setLimit($limit);
|
||||
|
||||
if (count($commits) === 0) {
|
||||
throw new ReferenceNotFoundException('The log is empty');
|
||||
}
|
||||
|
||||
return array_pop($commits);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getCommits()
|
||||
{
|
||||
$args = array('--encoding='.StringHelper::getEncoding(), '--format=raw');
|
||||
|
||||
if (null !== $this->offset) {
|
||||
$args[] = '--skip='.((int) $this->offset);
|
||||
}
|
||||
|
||||
if (null !== $this->limit) {
|
||||
$args[] = '-n';
|
||||
$args[] = (int) $this->limit;
|
||||
}
|
||||
|
||||
if (null !== $this->revisions) {
|
||||
$args = array_merge($args, $this->revisions->getAsTextArray());
|
||||
} else {
|
||||
$args[] = '--all';
|
||||
}
|
||||
|
||||
$args[] = '--';
|
||||
|
||||
$args = array_merge($args, $this->paths);
|
||||
|
||||
try {
|
||||
$output = $this->repository->run('log', $args);
|
||||
} catch (ProcessException $e) {
|
||||
throw new ReferenceNotFoundException(sprintf('Can not find revision "%s"', implode(' ', $this->revisions->getAsTextArray())), null, $e);
|
||||
}
|
||||
|
||||
$parser = new Parser\LogParser();
|
||||
$parser->parse($output);
|
||||
|
||||
$result = array();
|
||||
foreach ($parser->log as $commitData) {
|
||||
$hash = $commitData['id'];
|
||||
unset($commitData['id']);
|
||||
|
||||
$commit = $this->repository->getCommit($hash);
|
||||
$commit->setData($commitData);
|
||||
|
||||
$result[] = $commit;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Countable
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return $this->countCommits();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IteratorAggregate
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->getCommits());
|
||||
}
|
||||
|
||||
/**
|
||||
* Count commits, without offset or limit.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function countCommits()
|
||||
{
|
||||
if (null !== $this->revisions && count($this->revisions)) {
|
||||
$output = $this->repository->run('rev-list', array_merge(array('--count'), $this->revisions->getAsTextArray(), array('--'), $this->paths));
|
||||
} else {
|
||||
$output = $this->repository->run('rev-list', array_merge(array('--count', '--all', '--'), $this->paths));
|
||||
}
|
||||
|
||||
return (int) $output;
|
||||
}
|
||||
}
|
74
vendor/gitonomy/gitlib/src/Gitonomy/Git/Parser/BlameParser.php
vendored
Normal file
74
vendor/gitonomy/gitlib/src/Gitonomy/Git/Parser/BlameParser.php
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Parser;
|
||||
|
||||
use Gitonomy\Git\Blame\Line;
|
||||
use Gitonomy\Git\Repository;
|
||||
|
||||
class BlameParser extends ParserBase
|
||||
{
|
||||
public $lines;
|
||||
|
||||
protected $repository;
|
||||
|
||||
public function __construct(Repository $repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
protected function doParse()
|
||||
{
|
||||
$this->lines = array();
|
||||
|
||||
$memory = array();
|
||||
|
||||
$line = 1;
|
||||
while (!$this->isFinished()) {
|
||||
$hash = $this->consumeHash();
|
||||
$this->consume(' ');
|
||||
$vars = $this->consumeRegexp('/(\d+) (\d+)( (\d+))?/A');
|
||||
$sourceLine = $vars[1];
|
||||
$targetLine = $vars[2];
|
||||
$blockLine = isset($vars[4]) ? $vars[4] : null;
|
||||
$this->consumeTo("\n");
|
||||
$this->consumeNewLine();
|
||||
|
||||
if (!isset($memory[$hash])) {
|
||||
foreach (array('author', 'author-mail', 'author-time', 'author-tz',
|
||||
'committer', 'committer-mail', 'committer-time', 'committer-tz',
|
||||
'summary', ) as $key) {
|
||||
$this->consume($key);
|
||||
$this->consumeTo("\n");
|
||||
$this->consumeNewLine();
|
||||
}
|
||||
|
||||
if ($this->expects('previous ')) {
|
||||
$this->consumeTo("\n");
|
||||
$this->consumeNewLine();
|
||||
}
|
||||
|
||||
if ($this->expects('boundary')) {
|
||||
$this->consumeNewLine();
|
||||
}
|
||||
$this->consume('filename');
|
||||
$this->consumeTo("\n"); // filename
|
||||
$this->consumeNewLine();
|
||||
$memory[$hash] = $this->repository->getCommit($hash);
|
||||
}
|
||||
$content = $this->consumeTo("\n"); // content of line
|
||||
$this->consumeNewLine();
|
||||
|
||||
$this->lines[$line] = new Line($memory[$hash], $sourceLine, $targetLine, $blockLine, $content);
|
||||
++$line;
|
||||
}
|
||||
}
|
||||
}
|
79
vendor/gitonomy/gitlib/src/Gitonomy/Git/Parser/CommitParser.php
vendored
Normal file
79
vendor/gitonomy/gitlib/src/Gitonomy/Git/Parser/CommitParser.php
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Parser;
|
||||
|
||||
use Gitonomy\Git\Exception\RuntimeException;
|
||||
|
||||
class CommitParser extends ParserBase
|
||||
{
|
||||
public $tree;
|
||||
public $parents;
|
||||
public $authorName;
|
||||
public $authorEmail;
|
||||
public $authorDate;
|
||||
public $committerName;
|
||||
public $committerEmail;
|
||||
public $committerDate;
|
||||
public $message;
|
||||
|
||||
protected function doParse()
|
||||
{
|
||||
$this->consume('tree ');
|
||||
$this->tree = $this->consumeHash();
|
||||
$this->consumeNewLine();
|
||||
|
||||
$this->parents = array();
|
||||
while ($this->expects('parent ')) {
|
||||
$this->parents[] = $this->consumeHash();
|
||||
$this->consumeNewLine();
|
||||
}
|
||||
|
||||
$this->consume('author ');
|
||||
list($this->authorName, $this->authorEmail, $this->authorDate) = $this->consumeNameEmailDate();
|
||||
$this->authorDate = $this->parseDate($this->authorDate);
|
||||
$this->consumeNewLine();
|
||||
|
||||
$this->consume('committer ');
|
||||
list($this->committerName, $this->committerEmail, $this->committerDate) = $this->consumeNameEmailDate();
|
||||
$this->committerDate = $this->parseDate($this->committerDate);
|
||||
|
||||
// will consume an GPG signed commit if there is one
|
||||
$this->consumeGPGSignature();
|
||||
|
||||
$this->consumeNewLine();
|
||||
|
||||
$this->consumeNewLine();
|
||||
$this->message = $this->consumeAll();
|
||||
}
|
||||
|
||||
protected function consumeNameEmailDate()
|
||||
{
|
||||
if (!preg_match('/(([^\n]*) <([^\n]*)> (\d+ [+-]\d{4}))/A', $this->content, $vars, 0, $this->cursor)) {
|
||||
throw new RuntimeException('Unable to parse name, email and date');
|
||||
}
|
||||
|
||||
$this->cursor += strlen($vars[1]);
|
||||
|
||||
return array($vars[2], $vars[3], $vars[4]);
|
||||
}
|
||||
|
||||
protected function parseDate($text)
|
||||
{
|
||||
$date = \DateTime::createFromFormat('U e O', $text.' UTC');
|
||||
|
||||
if (!$date instanceof \DateTime) {
|
||||
throw new RuntimeException(sprintf('Unable to convert "%s" to datetime', $text));
|
||||
}
|
||||
|
||||
return $date;
|
||||
}
|
||||
}
|
133
vendor/gitonomy/gitlib/src/Gitonomy/Git/Parser/DiffParser.php
vendored
Normal file
133
vendor/gitonomy/gitlib/src/Gitonomy/Git/Parser/DiffParser.php
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Parser;
|
||||
|
||||
use Gitonomy\Git\Diff\File;
|
||||
use Gitonomy\Git\Diff\FileChange;
|
||||
|
||||
class DiffParser extends ParserBase
|
||||
{
|
||||
public $files;
|
||||
|
||||
protected function doParse()
|
||||
{
|
||||
$this->files = array();
|
||||
|
||||
while (!$this->isFinished()) {
|
||||
// 1. title
|
||||
$vars = $this->consumeRegexp('/diff --git (a\/.*) (b\/.*)\n/');
|
||||
$oldName = $vars[1];
|
||||
$newName = $vars[2];
|
||||
$oldIndex = null;
|
||||
$newIndex = null;
|
||||
$oldMode = null;
|
||||
$newMode = null;
|
||||
|
||||
// 2. mode
|
||||
if ($this->expects('new file mode ')) {
|
||||
$newMode = $this->consumeTo("\n");
|
||||
$this->consumeNewLine();
|
||||
$oldMode = null;
|
||||
}
|
||||
if ($this->expects('old mode ')) {
|
||||
$oldMode = $this->consumeTo("\n");
|
||||
$this->consumeNewLine();
|
||||
$this->consume('new mode ');
|
||||
$newMode = $this->consumeTo("\n");
|
||||
$this->consumeNewLine();
|
||||
}
|
||||
if ($this->expects('deleted file mode ')) {
|
||||
$oldMode = $this->consumeTo("\n");
|
||||
$newMode = null;
|
||||
$this->consumeNewLine();
|
||||
}
|
||||
|
||||
if ($this->expects('similarity index ')) {
|
||||
$this->consumeRegexp('/\d{1,3}%\n/');
|
||||
$this->consume('rename from ');
|
||||
$this->consumeTo("\n");
|
||||
$this->consumeNewLine();
|
||||
$this->consume('rename to ');
|
||||
$this->consumeTo("\n");
|
||||
$this->consumeNewLine();
|
||||
}
|
||||
|
||||
// 4. File informations
|
||||
$isBinary = false;
|
||||
if ($this->expects('index ')) {
|
||||
$oldIndex = $this->consumeShortHash();
|
||||
$this->consume('..');
|
||||
$newIndex = $this->consumeShortHash();
|
||||
if ($this->expects(' ')) {
|
||||
$vars = $this->consumeRegexp('/\d{6}/');
|
||||
$newMode = $oldMode = $vars[0];
|
||||
}
|
||||
$this->consumeNewLine();
|
||||
|
||||
if ($this->expects('--- ')) {
|
||||
$oldName = $this->consumeTo("\n");
|
||||
$this->consumeNewLine();
|
||||
$this->consume('+++ ');
|
||||
$newName = $this->consumeTo("\n");
|
||||
$this->consumeNewLine();
|
||||
} elseif ($this->expects('Binary files ')) {
|
||||
$vars = $this->consumeRegexp('/(.*) and (.*) differ\n/');
|
||||
$isBinary = true;
|
||||
$oldName = $vars[1];
|
||||
$newName = $vars[2];
|
||||
}
|
||||
}
|
||||
|
||||
$oldName = $oldName === '/dev/null' ? null : substr($oldName, 2);
|
||||
$newName = $newName === '/dev/null' ? null : substr($newName, 2);
|
||||
$oldIndex = preg_match('/^0+$/', $oldIndex) ? null : $oldIndex;
|
||||
$newIndex = preg_match('/^0+$/', $newIndex) ? null : $newIndex;
|
||||
$file = new File($oldName, $newName, $oldMode, $newMode, $oldIndex, $newIndex, $isBinary);
|
||||
|
||||
// 5. Diff
|
||||
while ($this->expects('@@ ')) {
|
||||
$vars = $this->consumeRegexp('/-(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))?/');
|
||||
$rangeOldStart = $vars[1];
|
||||
$rangeOldCount = $vars[2];
|
||||
$rangeNewStart = $vars[3];
|
||||
$rangeNewCount = isset($vars[4]) ? $vars[4] : $vars[2]; // @todo Ici, t'as pris un gros raccourci mon loulou
|
||||
$this->consume(' @@');
|
||||
$this->consumeTo("\n");
|
||||
$this->consumeNewLine();
|
||||
|
||||
// 6. Lines
|
||||
$lines = array();
|
||||
while (true) {
|
||||
if ($this->expects(' ')) {
|
||||
$lines[] = array(FileChange::LINE_CONTEXT, $this->consumeTo("\n"));
|
||||
} elseif ($this->expects('+')) {
|
||||
$lines[] = array(FileChange::LINE_ADD, $this->consumeTo("\n"));
|
||||
} elseif ($this->expects('-')) {
|
||||
$lines[] = array(FileChange::LINE_REMOVE, $this->consumeTo("\n"));
|
||||
} elseif ($this->expects("\ No newline at end of file")) {
|
||||
// Ignore this case...
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
$this->consumeNewLine();
|
||||
}
|
||||
|
||||
$change = new FileChange($rangeOldStart, $rangeOldCount, $rangeNewStart, $rangeNewCount, $lines);
|
||||
|
||||
$file->addChange($change);
|
||||
}
|
||||
|
||||
$this->files[] = $file;
|
||||
}
|
||||
}
|
||||
}
|
75
vendor/gitonomy/gitlib/src/Gitonomy/Git/Parser/LogParser.php
vendored
Normal file
75
vendor/gitonomy/gitlib/src/Gitonomy/Git/Parser/LogParser.php
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Parser;
|
||||
|
||||
class LogParser extends CommitParser
|
||||
{
|
||||
public $log = array();
|
||||
|
||||
protected function doParse()
|
||||
{
|
||||
$this->log = array();
|
||||
|
||||
while (!$this->isFinished()) {
|
||||
$commit = array();
|
||||
$this->consume('commit ');
|
||||
$commit['id'] = $this->consumeHash();
|
||||
$this->consumeNewLine();
|
||||
|
||||
$this->consume('tree ');
|
||||
$commit['treeHash'] = $this->consumeHash();
|
||||
$this->consumeNewLine();
|
||||
|
||||
$commit['parentHashes'] = array();
|
||||
while ($this->expects('parent ')) {
|
||||
$commit['parentHashes'][] = $this->consumeHash();
|
||||
$this->consumeNewLine();
|
||||
}
|
||||
|
||||
$this->consume('author ');
|
||||
list($commit['authorName'], $commit['authorEmail'], $commit['authorDate']) = $this->consumeNameEmailDate();
|
||||
$commit['authorDate'] = $this->parseDate($commit['authorDate']);
|
||||
$this->consumeNewLine();
|
||||
|
||||
$this->consume('committer ');
|
||||
list($commit['committerName'], $commit['committerEmail'], $commit['committerDate']) = $this->consumeNameEmailDate();
|
||||
$commit['committerDate'] = $this->parseDate($commit['committerDate']);
|
||||
|
||||
// will consume an GPG signed commit if there is one
|
||||
$this->consumeGPGSignature();
|
||||
|
||||
$this->consumeNewLine();
|
||||
$this->consumeNewLine();
|
||||
|
||||
$message = '';
|
||||
if ($this->expects(' ')) {
|
||||
$this->cursor -= strlen(' ');
|
||||
|
||||
while ($this->expects(' ')) {
|
||||
$message .= $this->consumeTo("\n")."\n";
|
||||
$this->consumeNewLine();
|
||||
}
|
||||
}
|
||||
else {
|
||||
$this->cursor--;
|
||||
}
|
||||
|
||||
if (!$this->isFinished()) {
|
||||
$this->consumeNewLine();
|
||||
}
|
||||
|
||||
$commit['message'] = $message;
|
||||
|
||||
$this->log[] = $commit;
|
||||
}
|
||||
}
|
||||
}
|
137
vendor/gitonomy/gitlib/src/Gitonomy/Git/Parser/ParserBase.php
vendored
Normal file
137
vendor/gitonomy/gitlib/src/Gitonomy/Git/Parser/ParserBase.php
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Parser;
|
||||
|
||||
use Gitonomy\Git\Exception\RuntimeException;
|
||||
|
||||
abstract class ParserBase
|
||||
{
|
||||
protected $cursor;
|
||||
protected $content;
|
||||
protected $length;
|
||||
|
||||
abstract protected function doParse();
|
||||
|
||||
public function parse($content)
|
||||
{
|
||||
$this->cursor = 0;
|
||||
$this->content = $content;
|
||||
$this->length = strlen($this->content);
|
||||
|
||||
$this->doParse();
|
||||
}
|
||||
|
||||
protected function isFinished()
|
||||
{
|
||||
return $this->cursor === $this->length;
|
||||
}
|
||||
|
||||
protected function consumeAll()
|
||||
{
|
||||
$rest = substr($this->content, $this->cursor);
|
||||
$this->cursor += strlen($rest);
|
||||
|
||||
return $rest;
|
||||
}
|
||||
|
||||
protected function expects($expected)
|
||||
{
|
||||
$length = strlen($expected);
|
||||
$actual = substr($this->content, $this->cursor, $length);
|
||||
if ($actual !== $expected) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->cursor += $length;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function consumeShortHash()
|
||||
{
|
||||
if (!preg_match('/([A-Za-z0-9]{7,40})/A', $this->content, $vars, null, $this->cursor)) {
|
||||
throw new RuntimeException('No short hash found: '.substr($this->content, $this->cursor, 7));
|
||||
}
|
||||
|
||||
$this->cursor += strlen($vars[1]);
|
||||
|
||||
return $vars[1];
|
||||
}
|
||||
|
||||
protected function consumeHash()
|
||||
{
|
||||
if (!preg_match('/([A-Za-z0-9]{40})/A', $this->content, $vars, null, $this->cursor)) {
|
||||
throw new RuntimeException('No hash found: '.substr($this->content, $this->cursor, 40));
|
||||
}
|
||||
|
||||
$this->cursor += 40;
|
||||
|
||||
return $vars[1];
|
||||
}
|
||||
|
||||
protected function consumeRegexp($regexp)
|
||||
{
|
||||
if (!preg_match($regexp.'A', $this->content, $vars, null, $this->cursor)) {
|
||||
throw new RuntimeException('No match for regexp '.$regexp.' Upcoming: '.substr($this->content, $this->cursor, 30));
|
||||
}
|
||||
|
||||
$this->cursor += strlen($vars[0]);
|
||||
|
||||
return $vars;
|
||||
}
|
||||
|
||||
protected function consumeTo($text)
|
||||
{
|
||||
$pos = strpos($this->content, $text, $this->cursor);
|
||||
|
||||
if (false === $pos) {
|
||||
throw new RuntimeException(sprintf('Unable to find "%s"', $text));
|
||||
}
|
||||
|
||||
$result = substr($this->content, $this->cursor, $pos - $this->cursor);
|
||||
$this->cursor = $pos;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function consume($expected)
|
||||
{
|
||||
$length = strlen($expected);
|
||||
$actual = substr($this->content, $this->cursor, $length);
|
||||
if ($actual !== $expected) {
|
||||
throw new RuntimeException(sprintf('Expected "%s", but got "%s" (%s)', $expected, $actual, substr($this->content, $this->cursor, 10)));
|
||||
}
|
||||
$this->cursor += $length;
|
||||
|
||||
return $expected;
|
||||
}
|
||||
|
||||
protected function consumeNewLine()
|
||||
{
|
||||
return $this->consume("\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function consumeGPGSignature() {
|
||||
$expected = "\ngpgsig ";
|
||||
$length = strlen($expected);
|
||||
$actual = substr($this->content, $this->cursor, $length);
|
||||
if($actual != $expected) {
|
||||
return '';
|
||||
}
|
||||
$this->cursor += $length;
|
||||
|
||||
return $this->consumeTo("\n\n");
|
||||
}
|
||||
}
|
30
vendor/gitonomy/gitlib/src/Gitonomy/Git/Parser/ReferenceParser.php
vendored
Normal file
30
vendor/gitonomy/gitlib/src/Gitonomy/Git/Parser/ReferenceParser.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Parser;
|
||||
|
||||
class ReferenceParser extends ParserBase
|
||||
{
|
||||
public $references;
|
||||
|
||||
protected function doParse()
|
||||
{
|
||||
$this->references = array();
|
||||
|
||||
while (!$this->isFinished()) {
|
||||
$hash = $this->consumeHash();
|
||||
$this->consume(' ');
|
||||
$name = $this->consumeTo("\n");
|
||||
$this->consumeNewLine();
|
||||
$this->references[] = array($hash, $name);
|
||||
}
|
||||
}
|
||||
}
|
38
vendor/gitonomy/gitlib/src/Gitonomy/Git/Parser/TreeParser.php
vendored
Normal file
38
vendor/gitonomy/gitlib/src/Gitonomy/Git/Parser/TreeParser.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Parser;
|
||||
|
||||
class TreeParser extends ParserBase
|
||||
{
|
||||
public $entries = array();
|
||||
|
||||
protected function doParse()
|
||||
{
|
||||
while (!$this->isFinished()) {
|
||||
$vars = $this->consumeRegexp('/\d{6}/A');
|
||||
$mode = $vars[0];
|
||||
$this->consume(' ');
|
||||
|
||||
$vars = $this->consumeRegexp('/(blob|tree|commit)/A');
|
||||
$type = $vars[0];
|
||||
$this->consume(' ');
|
||||
|
||||
$hash = $this->consumeHash();
|
||||
$this->consume("\t");
|
||||
|
||||
$name = $this->consumeTo("\n");
|
||||
$this->consumeNewLine();
|
||||
|
||||
$this->entries[] = array($mode, $type, $hash, $name);
|
||||
}
|
||||
}
|
||||
}
|
169
vendor/gitonomy/gitlib/src/Gitonomy/Git/PushReference.php
vendored
Normal file
169
vendor/gitonomy/gitlib/src/Gitonomy/Git/PushReference.php
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git;
|
||||
|
||||
use Gitonomy\Git\Exception\LogicException;
|
||||
|
||||
/**
|
||||
* Push reference contains a commit interval. This object aggregates methods
|
||||
* for this interval.
|
||||
*
|
||||
* @author Julien DIDIER <genzo.wm@gmail.com>
|
||||
*/
|
||||
class PushReference
|
||||
{
|
||||
const ZERO = '0000000000000000000000000000000000000000';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $reference;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $before;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $after;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $isForce;
|
||||
|
||||
public function __construct(Repository $repository, $reference, $before, $after)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
$this->reference = $reference;
|
||||
$this->before = $before;
|
||||
$this->after = $after;
|
||||
$this->isForce = $this->getForce();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Repository
|
||||
*/
|
||||
public function getRepository()
|
||||
{
|
||||
return $this->repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getReference()
|
||||
{
|
||||
return $this->reference;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBefore()
|
||||
{
|
||||
return $this->before;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAfter()
|
||||
{
|
||||
return $this->after;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLog($excludes = array())
|
||||
{
|
||||
return $this->repository->getLog(array_merge(
|
||||
array($this->getRevision()),
|
||||
array_map(function ($e) {
|
||||
return '^'.$e;
|
||||
}, $excludes)
|
||||
));
|
||||
}
|
||||
|
||||
public function getRevision()
|
||||
{
|
||||
if ($this->isDelete()) {
|
||||
throw new LogicException('No revision for deletion');
|
||||
}
|
||||
|
||||
if ($this->isCreate()) {
|
||||
return $this->getAfter();
|
||||
}
|
||||
|
||||
return $this->getBefore().'..'.$this->getAfter();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isCreate()
|
||||
{
|
||||
return $this->isZero($this->before);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isDelete()
|
||||
{
|
||||
return $this->isZero($this->after);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isForce()
|
||||
{
|
||||
return $this->isForce;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isFastForward()
|
||||
{
|
||||
return !$this->isDelete() && !$this->isCreate() && !$this->isForce();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function isZero($reference)
|
||||
{
|
||||
return self::ZERO === $reference;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function getForce()
|
||||
{
|
||||
if ($this->isDelete() || $this->isCreate()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = $this->repository->run('merge-base', array(
|
||||
$this->before,
|
||||
$this->after,
|
||||
));
|
||||
|
||||
return $this->before !== trim($result);
|
||||
}
|
||||
}
|
70
vendor/gitonomy/gitlib/src/Gitonomy/Git/Reference.php
vendored
Normal file
70
vendor/gitonomy/gitlib/src/Gitonomy/Git/Reference.php
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git;
|
||||
|
||||
/**
|
||||
* Reference in a Git repository.
|
||||
*
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* @author Julien DIDIER <genzo.wm@gmail.com>
|
||||
*/
|
||||
abstract class Reference extends Revision
|
||||
{
|
||||
protected $commitHash;
|
||||
|
||||
public function __construct(Repository $repository, $revision, $commitHash = null)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
$this->revision = $revision;
|
||||
$this->commitHash = $commitHash;
|
||||
}
|
||||
|
||||
public function getFullname()
|
||||
{
|
||||
return $this->revision;
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$this->repository->getReferences()->delete($this->getFullname());
|
||||
}
|
||||
|
||||
public function getCommitHash()
|
||||
{
|
||||
if (null !== $this->commitHash) {
|
||||
return $this->commitHash;
|
||||
}
|
||||
|
||||
try {
|
||||
$result = $this->repository->run('rev-parse', array('--verify', $this->revision));
|
||||
} catch (ProcessException $e) {
|
||||
throw new ReferenceNotFoundException(sprintf('Can not find revision "%s"', $this->revision));
|
||||
}
|
||||
|
||||
return $this->commitHash = trim($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the commit associated to the reference.
|
||||
*
|
||||
* @return Commit
|
||||
*/
|
||||
public function getCommit()
|
||||
{
|
||||
return $this->repository->getCommit($this->getCommitHash());
|
||||
}
|
||||
|
||||
public function getLastModification($path = null)
|
||||
{
|
||||
return $this->getCommit()->getLastModification($path);
|
||||
}
|
||||
}
|
61
vendor/gitonomy/gitlib/src/Gitonomy/Git/Reference/Branch.php
vendored
Normal file
61
vendor/gitonomy/gitlib/src/Gitonomy/Git/Reference/Branch.php
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Reference;
|
||||
|
||||
use Gitonomy\Git\Exception\RuntimeException;
|
||||
use Gitonomy\Git\Reference;
|
||||
|
||||
/**
|
||||
* Representation of a branch reference.
|
||||
*
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*/
|
||||
class Branch extends Reference
|
||||
{
|
||||
private $local = null;
|
||||
|
||||
public function getName()
|
||||
{
|
||||
$fullname = $this->getFullname();
|
||||
|
||||
if (preg_match('#^refs/heads/(?<name>.*)$#', $fullname, $vars)) {
|
||||
return $vars['name'];
|
||||
}
|
||||
|
||||
if (preg_match('#^refs/remotes/(?<remote>[^/]*)/(?<name>.*)$#', $fullname, $vars)) {
|
||||
return $vars['remote'].'/'.$vars['name'];
|
||||
}
|
||||
|
||||
throw new RuntimeException(sprintf('Cannot extract branch name from "%s"', $fullname));
|
||||
}
|
||||
|
||||
public function isRemote()
|
||||
{
|
||||
$this->detectBranchType();
|
||||
|
||||
return !$this->local;
|
||||
}
|
||||
|
||||
public function isLocal()
|
||||
{
|
||||
$this->detectBranchType();
|
||||
|
||||
return $this->local;
|
||||
}
|
||||
|
||||
private function detectBranchType()
|
||||
{
|
||||
if (null === $this->local) {
|
||||
$this->local = !preg_match('#^refs/remotes/(?<remote>[^/]*)/(?<name>.*)$#', $this->getFullname());
|
||||
}
|
||||
}
|
||||
}
|
25
vendor/gitonomy/gitlib/src/Gitonomy/Git/Reference/Stash.php
vendored
Normal file
25
vendor/gitonomy/gitlib/src/Gitonomy/Git/Reference/Stash.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Reference;
|
||||
|
||||
use Gitonomy\Git\Reference;
|
||||
|
||||
/**
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*/
|
||||
class Stash extends Reference
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'stash';
|
||||
}
|
||||
}
|
32
vendor/gitonomy/gitlib/src/Gitonomy/Git/Reference/Tag.php
vendored
Normal file
32
vendor/gitonomy/gitlib/src/Gitonomy/Git/Reference/Tag.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Reference;
|
||||
|
||||
use Gitonomy\Git\Exception\RuntimeException;
|
||||
use Gitonomy\Git\Reference;
|
||||
|
||||
/**
|
||||
* Representation of a tag reference.
|
||||
*
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*/
|
||||
class Tag extends Reference
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
if (!preg_match('#^refs/tags/(.*)$#', $this->revision, $vars)) {
|
||||
throw new RuntimeException(sprintf('Cannot extract tag name from "%s"', $this->revision));
|
||||
}
|
||||
|
||||
return $vars[1];
|
||||
}
|
||||
}
|
399
vendor/gitonomy/gitlib/src/Gitonomy/Git/ReferenceBag.php
vendored
Normal file
399
vendor/gitonomy/gitlib/src/Gitonomy/Git/ReferenceBag.php
vendored
Normal file
@@ -0,0 +1,399 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git;
|
||||
|
||||
use Gitonomy\Git\Exception\ReferenceNotFoundException;
|
||||
use Gitonomy\Git\Exception\RuntimeException;
|
||||
use Gitonomy\Git\Reference\Branch;
|
||||
use Gitonomy\Git\Reference\Stash;
|
||||
use Gitonomy\Git\Reference\Tag;
|
||||
|
||||
/**
|
||||
* Reference set associated to a repository.
|
||||
*
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* @author Julien DIDIER <genzo.wm@gmail.com>
|
||||
*/
|
||||
class ReferenceBag implements \Countable, \IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* Repository object.
|
||||
*
|
||||
* @var Gitonomy\Git\Repository
|
||||
*/
|
||||
protected $repository;
|
||||
|
||||
/**
|
||||
* Associative array of fullname references.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $references;
|
||||
|
||||
/**
|
||||
* List with all tags.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $tags;
|
||||
|
||||
/**
|
||||
* List with all branches.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $branches;
|
||||
|
||||
/**
|
||||
* A boolean indicating if the bag is already initialized.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $initialized = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Gitonomy\Git\Repository $repository The repository
|
||||
*/
|
||||
public function __construct($repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
$this->references = array();
|
||||
$this->tags = array();
|
||||
$this->branches = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference, by name.
|
||||
*
|
||||
* @param string $fullname Fullname of the reference (refs/heads/master, for example).
|
||||
*
|
||||
* @return Reference A reference object.
|
||||
*/
|
||||
public function get($fullname)
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
if (!isset($this->references[$fullname])) {
|
||||
throw new ReferenceNotFoundException($fullname);
|
||||
}
|
||||
|
||||
return $this->references[$fullname];
|
||||
}
|
||||
|
||||
public function has($fullname)
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
return isset($this->references[$fullname]);
|
||||
}
|
||||
|
||||
public function update(Reference $reference)
|
||||
{
|
||||
$fullname = $reference->getFullname();
|
||||
|
||||
$this->initialize();
|
||||
$this->repository->run('update-ref', array($fullname, $reference->getCommitHash()));
|
||||
|
||||
$this->references[$fullname] = $reference;
|
||||
|
||||
return $reference;
|
||||
}
|
||||
|
||||
public function createBranch($name, $commitHash)
|
||||
{
|
||||
$branch = new Branch($this->repository, 'refs/heads/'.$name, $commitHash);
|
||||
|
||||
return $this->update($branch);
|
||||
}
|
||||
|
||||
public function createTag($name, $commitHash)
|
||||
{
|
||||
$tag = new Tag($this->repository, 'refs/tags/'.$name, $commitHash);
|
||||
|
||||
return $this->update($tag);
|
||||
}
|
||||
|
||||
public function delete($fullname)
|
||||
{
|
||||
$this->repository->run('update-ref', array('-d', $fullname));
|
||||
|
||||
unset($this->references[$fullname]);
|
||||
}
|
||||
|
||||
public function hasBranches()
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
return count($this->branches) > 0;
|
||||
}
|
||||
|
||||
public function hasBranch($name)
|
||||
{
|
||||
return $this->has('refs/heads/'.$name);
|
||||
}
|
||||
|
||||
public function hasRemoteBranch($name)
|
||||
{
|
||||
return $this->has('refs/remotes/'.$name);
|
||||
}
|
||||
|
||||
public function hasTag($name)
|
||||
{
|
||||
return $this->has('refs/tags/'.$name);
|
||||
}
|
||||
|
||||
public function getFirstBranch()
|
||||
{
|
||||
$this->initialize();
|
||||
reset($this->branches);
|
||||
|
||||
return current($this->references);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array An array of Tag objects
|
||||
*/
|
||||
public function resolveTags($hash)
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
if ($hash instanceof Commit) {
|
||||
$hash = $hash->getHash();
|
||||
}
|
||||
|
||||
$tags = array();
|
||||
foreach ($this->references as $reference) {
|
||||
if ($reference instanceof Reference\Tag && $reference->getCommitHash() === $hash) {
|
||||
$tags[] = $reference;
|
||||
}
|
||||
}
|
||||
|
||||
return $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array An array of Branch objects
|
||||
*/
|
||||
public function resolveBranches($hash)
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
if ($hash instanceof Commit) {
|
||||
$hash = $hash->getHash();
|
||||
}
|
||||
|
||||
$branches = array();
|
||||
foreach ($this->references as $reference) {
|
||||
if ($reference instanceof Reference\Branch && $reference->getCommitHash() === $hash) {
|
||||
$branches[] = $reference;
|
||||
}
|
||||
}
|
||||
|
||||
return $branches;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array An array of references
|
||||
*/
|
||||
public function resolve($hash)
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
if ($hash instanceof Commit) {
|
||||
$hash = $hash->getHash();
|
||||
}
|
||||
|
||||
$result = array();
|
||||
foreach ($this->references as $k => $reference) {
|
||||
if ($reference->getCommitHash() === $hash) {
|
||||
$result[] = $reference;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all tags.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTags()
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
return $this->tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all branches.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getBranches()
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
$result = array();
|
||||
foreach ($this->references as $reference) {
|
||||
if ($reference instanceof Reference\Branch) {
|
||||
$result[] = $reference;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all locales branches.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLocalBranches()
|
||||
{
|
||||
$result = array();
|
||||
foreach ($this->getBranches() as $branch) {
|
||||
if ($branch->isLocal()) {
|
||||
$result[] = $branch;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all remote branches.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRemoteBranches()
|
||||
{
|
||||
$result = array();
|
||||
foreach ($this->getBranches() as $branch) {
|
||||
if ($branch->isRemote()) {
|
||||
$result[] = $branch;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array An associative array with fullname as key (refs/heads/master, refs/tags/0.1)
|
||||
*/
|
||||
public function getAll()
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
return $this->references;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Tag
|
||||
*/
|
||||
public function getTag($name)
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
return $this->get('refs/tags/'.$name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Branch
|
||||
*/
|
||||
public function getBranch($name)
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
return $this->get('refs/heads/'.$name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Branch
|
||||
*/
|
||||
public function getRemoteBranch($name)
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
return $this->get('refs/remotes/'.$name);
|
||||
}
|
||||
|
||||
protected function initialize()
|
||||
{
|
||||
if (true === $this->initialized) {
|
||||
return;
|
||||
}
|
||||
$this->initialized = true;
|
||||
|
||||
try {
|
||||
$parser = new Parser\ReferenceParser();
|
||||
$output = $this->repository->run('show-ref');
|
||||
} catch (RuntimeException $e) {
|
||||
$output = $e->getOutput();
|
||||
$error = $e->getErrorOutput();
|
||||
if ($error) {
|
||||
throw new RuntimeException('Error while getting list of references: '.$error);
|
||||
}
|
||||
}
|
||||
$parser->parse($output);
|
||||
|
||||
foreach ($parser->references as $row) {
|
||||
list($commitHash, $fullname) = $row;
|
||||
|
||||
if (preg_match('#^refs/(heads|remotes)/(.*)$#', $fullname)) {
|
||||
if (preg_match('#.*HEAD$#', $fullname)) {
|
||||
continue;
|
||||
}
|
||||
$reference = new Branch($this->repository, $fullname, $commitHash);
|
||||
$this->references[$fullname] = $reference;
|
||||
$this->branches[] = $reference;
|
||||
} elseif (preg_match('#^refs/tags/(.*)$#', $fullname)) {
|
||||
$reference = new Tag($this->repository, $fullname, $commitHash);
|
||||
$this->references[$fullname] = $reference;
|
||||
$this->tags[] = $reference;
|
||||
} elseif ($fullname === 'refs/stash') {
|
||||
$reference = new Stash($this->repository, $fullname, $commitHash);
|
||||
$this->references[$fullname] = $reference;
|
||||
} elseif (preg_match('#^refs/pull/(.*)$#', $fullname)) {
|
||||
// Do nothing here
|
||||
} elseif ($fullname === 'refs/notes/gtm-data') {
|
||||
// Do nothing here
|
||||
} else {
|
||||
throw new RuntimeException(sprintf('Unable to parse "%s"', $fullname));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*
|
||||
* @see Countable
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
return count($this->references);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IteratorAggregate
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
return new \ArrayIterator($this->references);
|
||||
}
|
||||
}
|
667
vendor/gitonomy/gitlib/src/Gitonomy/Git/Repository.php
vendored
Normal file
667
vendor/gitonomy/gitlib/src/Gitonomy/Git/Repository.php
vendored
Normal file
@@ -0,0 +1,667 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git;
|
||||
|
||||
use Gitonomy\Git\Diff\Diff;
|
||||
use Gitonomy\Git\Exception\InvalidArgumentException;
|
||||
use Gitonomy\Git\Exception\ProcessException;
|
||||
use Gitonomy\Git\Exception\RuntimeException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Process\Process;
|
||||
use Symfony\Component\Process\ProcessUtils;
|
||||
|
||||
/**
|
||||
* Git repository object.
|
||||
*
|
||||
* Main entry point for browsing a Git repository.
|
||||
*
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*/
|
||||
class Repository
|
||||
{
|
||||
const DEFAULT_DESCRIPTION = "Unnamed repository; edit this file 'description' to name the repository.\n";
|
||||
|
||||
/**
|
||||
* Directory containing git files.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $gitDir;
|
||||
|
||||
/**
|
||||
* Working directory.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $workingDir;
|
||||
|
||||
/**
|
||||
* Cache containing all objects of the repository.
|
||||
*
|
||||
* Associative array, indexed by object hash
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $objects;
|
||||
|
||||
/**
|
||||
* Reference bag associated to this repository.
|
||||
*
|
||||
* @var ReferenceBag
|
||||
*/
|
||||
protected $referenceBag;
|
||||
|
||||
/**
|
||||
* Logger (can be null).
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* Path to git command.
|
||||
*/
|
||||
protected $command;
|
||||
|
||||
/**
|
||||
* Debug flag, indicating if errors should be thrown.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $debug;
|
||||
|
||||
/**
|
||||
* Environment variables that should be set for every running process.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $environmentVariables;
|
||||
|
||||
/**
|
||||
* Timeout that should be set for every running process.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $processTimeout;
|
||||
|
||||
/**
|
||||
* Constructs a new repository.
|
||||
*
|
||||
* Available options are:
|
||||
*
|
||||
* * working_dir : specify where working copy is located (option --work-tree)
|
||||
*
|
||||
* * debug : (default: true) enable/disable minimize errors and reduce log level
|
||||
*
|
||||
* * logger : a logger to use for logging actions (Psr\Log\LoggerInterface)
|
||||
*
|
||||
* * environment_variables : define environment variables for every ran process
|
||||
*
|
||||
* @param string $dir path to git repository
|
||||
* @param array $options array of options values
|
||||
*
|
||||
* @throws InvalidArgumentException The folder does not exists
|
||||
*/
|
||||
public function __construct($dir, $options = array())
|
||||
{
|
||||
$is_windows = defined('PHP_WINDOWS_VERSION_BUILD');
|
||||
$options = array_merge(array(
|
||||
'working_dir' => null,
|
||||
'debug' => true,
|
||||
'logger' => null,
|
||||
'environment_variables' => $is_windows ? array('PATH' => getenv('path')) : array(),
|
||||
'command' => 'git',
|
||||
'process_timeout' => 3600,
|
||||
), $options);
|
||||
|
||||
if (null !== $options['logger'] && !$options['logger'] instanceof LoggerInterface) {
|
||||
throw new InvalidArgumentException(sprintf('Argument "logger" passed to Repository should be a Psr\Log\LoggerInterface. A %s was provided', is_object($options['logger']) ? get_class($options['logger']) : gettype($options['logger'])));
|
||||
}
|
||||
|
||||
$this->logger = $options['logger'];
|
||||
$this->initDir($dir, $options['working_dir']);
|
||||
|
||||
$this->objects = array();
|
||||
$this->debug = (bool) $options['debug'];
|
||||
$this->environmentVariables = $options['environment_variables'];
|
||||
$this->processTimeout = $options['process_timeout'];
|
||||
$this->command = $options['command'];
|
||||
|
||||
if (true === $this->debug && null !== $this->logger) {
|
||||
$this->logger->debug(sprintf('Repository created (git dir: "%s", working dir: "%s")', $this->gitDir, $this->workingDir ?: 'none'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes directory attributes on repository:.
|
||||
*
|
||||
* @param string $gitDir directory of a working copy with files checked out
|
||||
* @param string $workingDir directory containing git files (objects, config...)
|
||||
*/
|
||||
private function initDir($gitDir, $workingDir = null)
|
||||
{
|
||||
$realGitDir = realpath($gitDir);
|
||||
|
||||
if (false === $realGitDir) {
|
||||
throw new InvalidArgumentException(sprintf('Directory "%s" does not exist or is not a directory', $gitDir));
|
||||
} else if (!is_dir($realGitDir)) {
|
||||
throw new InvalidArgumentException(sprintf('Directory "%s" does not exist or is not a directory', $realGitDir));
|
||||
} elseif (null === $workingDir && is_dir($realGitDir.'/.git')) {
|
||||
$workingDir = $realGitDir;
|
||||
$realGitDir = $realGitDir.'/.git';
|
||||
}
|
||||
|
||||
$this->gitDir = $realGitDir;
|
||||
$this->workingDir = $workingDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if repository is a bare repository.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isBare()
|
||||
{
|
||||
return null === $this->workingDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HEAD resolved as a commit.
|
||||
*
|
||||
* @return Commit|null returns a Commit or ``null`` if repository is empty
|
||||
*/
|
||||
public function getHeadCommit()
|
||||
{
|
||||
$head = $this->getHead();
|
||||
|
||||
if ($head instanceof Reference) {
|
||||
return $head->getCommit();
|
||||
}
|
||||
|
||||
return $head;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException Unable to find file HEAD (debug-mode only)
|
||||
*
|
||||
* @return Reference|Commit|null current HEAD object or null if error occurs
|
||||
*/
|
||||
public function getHead()
|
||||
{
|
||||
$file = $this->gitDir.'/HEAD';
|
||||
|
||||
if (!file_exists($file)) {
|
||||
$message = sprintf('Unable to find HEAD file ("%s")', $file);
|
||||
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->error($message);
|
||||
}
|
||||
|
||||
if (true === $this->debug) {
|
||||
throw new RuntimeException($message);
|
||||
}
|
||||
}
|
||||
|
||||
$content = trim(file_get_contents($file));
|
||||
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug('HEAD file read: '.$content);
|
||||
}
|
||||
|
||||
if (preg_match('/^ref: (.+)$/', $content, $vars)) {
|
||||
return $this->getReferences()->get($vars[1]);
|
||||
} elseif (preg_match('/^[0-9a-f]{40}$/', $content)) {
|
||||
return $this->getCommit($content);
|
||||
}
|
||||
|
||||
$message = sprintf('Unexpected HEAD file content (file: %s). Content of file: %s', $file, $content);
|
||||
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->error($message);
|
||||
}
|
||||
|
||||
if (true === $this->debug) {
|
||||
throw new RuntimeException($message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isHeadDetached()
|
||||
{
|
||||
return !$this->isHeadAttached();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isHeadAttached()
|
||||
{
|
||||
return $this->getHead() instanceof Reference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path to the git repository.
|
||||
*
|
||||
* @return string A directory path
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->workingDir === null ? $this->gitDir : $this->workingDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the directory containing git files (git-dir).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getGitDir()
|
||||
{
|
||||
return $this->gitDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the work-tree directory. This may be null if repository is
|
||||
* bare.
|
||||
*
|
||||
* @return string path to repository or null if repository is bare
|
||||
*/
|
||||
public function getWorkingDir()
|
||||
{
|
||||
return $this->workingDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instanciates a revision.
|
||||
*
|
||||
* @param string $name Name of the revision
|
||||
*
|
||||
* @return Revision
|
||||
*/
|
||||
public function getRevision($name)
|
||||
{
|
||||
return new Revision($this, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WorkingCopy
|
||||
*/
|
||||
public function getWorkingCopy()
|
||||
{
|
||||
return new WorkingCopy($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reference list associated to the repository.
|
||||
*
|
||||
* @return ReferenceBag
|
||||
*/
|
||||
public function getReferences()
|
||||
{
|
||||
if (null === $this->referenceBag) {
|
||||
$this->referenceBag = new ReferenceBag($this);
|
||||
}
|
||||
|
||||
return $this->referenceBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instanciates a commit object or fetches one from the cache.
|
||||
*
|
||||
* @param string $hash A commit hash, with a length of 40
|
||||
*
|
||||
* @return Commit
|
||||
*/
|
||||
public function getCommit($hash)
|
||||
{
|
||||
if (!isset($this->objects[$hash])) {
|
||||
$this->objects[$hash] = new Commit($this, $hash);
|
||||
}
|
||||
|
||||
return $this->objects[$hash];
|
||||
}
|
||||
|
||||
/**
|
||||
* Instanciates a tree object or fetches one from the cache.
|
||||
*
|
||||
* @param string $hash A tree hash, with a length of 40
|
||||
*
|
||||
* @return Tree
|
||||
*/
|
||||
public function getTree($hash)
|
||||
{
|
||||
if (!isset($this->objects[$hash])) {
|
||||
$this->objects[$hash] = new Tree($this, $hash);
|
||||
}
|
||||
|
||||
return $this->objects[$hash];
|
||||
}
|
||||
|
||||
/**
|
||||
* Instanciates a blob object or fetches one from the cache.
|
||||
*
|
||||
* @param string $hash A blob hash, with a length of 40
|
||||
*
|
||||
* @return Blob
|
||||
*/
|
||||
public function getBlob($hash)
|
||||
{
|
||||
if (!isset($this->objects[$hash])) {
|
||||
$this->objects[$hash] = new Blob($this, $hash);
|
||||
}
|
||||
|
||||
return $this->objects[$hash];
|
||||
}
|
||||
|
||||
public function getBlame($revision, $file, $lineRange = null)
|
||||
{
|
||||
if (is_string($revision)) {
|
||||
$revision = $this->getRevision($revision);
|
||||
}
|
||||
|
||||
return new Blame($this, $revision, $file, $lineRange);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns log for a given set of revisions and paths.
|
||||
*
|
||||
* All those values can be null, meaning everything.
|
||||
*
|
||||
* @param array $revisions An array of revisions to show logs from. Can be
|
||||
* any text value type
|
||||
* @param array $paths Restrict log to modifications occurring on given
|
||||
* paths.
|
||||
* @param int $offset Start from a given offset in results.
|
||||
* @param int $limit Limit number of total results.
|
||||
*
|
||||
* @return Log
|
||||
*/
|
||||
public function getLog($revisions = null, $paths = null, $offset = null, $limit = null)
|
||||
{
|
||||
return new Log($this, $revisions, $paths, $offset, $limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Diff
|
||||
*/
|
||||
public function getDiff($revisions)
|
||||
{
|
||||
if (null !== $revisions && !$revisions instanceof RevisionList) {
|
||||
$revisions = new RevisionList($this, $revisions);
|
||||
}
|
||||
|
||||
$args = array_merge(array('-r', '-p', '-m', '-M', '--no-commit-id', '--full-index'), $revisions->getAsTextArray());
|
||||
|
||||
$diff = Diff::parse($this->run('diff', $args));
|
||||
$diff->setRepository($this);
|
||||
|
||||
return $diff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of repository, in kilobytes.
|
||||
*
|
||||
* @return int A sum, in kilobytes
|
||||
*
|
||||
* @throws RuntimeException An error occurred while computing size
|
||||
*/
|
||||
public function getSize()
|
||||
{
|
||||
$commandlineArguments = array('du', '-skc', $this->gitDir);
|
||||
$commandline = $this->normalizeCommandlineArguments($commandlineArguments);
|
||||
$process = new Process($commandline);
|
||||
$process->run();
|
||||
|
||||
if (!preg_match('/(\d+)\s+total$/', trim($process->getOutput()), $vars)) {
|
||||
$message = sprintf("Unable to parse process output\ncommand: %s\noutput: %s", $process->getCommandLine(), $process->getOutput());
|
||||
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->error($message);
|
||||
}
|
||||
|
||||
if (true === $this->debug) {
|
||||
throw new RuntimeException('unable to parse repository size output');
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return $vars[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a shell command on the repository, using PHP pipes.
|
||||
*
|
||||
* @param string $command The command to execute
|
||||
*/
|
||||
public function shell($command, array $env = array())
|
||||
{
|
||||
$argument = sprintf('%s \'%s\'', $command, $this->gitDir);
|
||||
|
||||
$prefix = '';
|
||||
foreach ($env as $name => $value) {
|
||||
$prefix .= sprintf('export %s=%s;', escapeshellarg($name), escapeshellarg($value));
|
||||
}
|
||||
|
||||
proc_open($prefix.'git shell -c '.escapeshellarg($argument), array(STDIN, STDOUT, STDERR), $pipes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hooks object.
|
||||
*
|
||||
* @return Hooks
|
||||
*/
|
||||
public function getHooks()
|
||||
{
|
||||
return new Hooks($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of repository from description file in git directory.
|
||||
*
|
||||
* @return string The description
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
$file = $this->gitDir.'/description';
|
||||
$exists = is_file($file);
|
||||
|
||||
if (null !== $this->logger && true === $this->debug) {
|
||||
if (false === $exists) {
|
||||
$this->logger->debug(sprintf('no description file in repository ("%s")', $file));
|
||||
} else {
|
||||
$this->logger->debug(sprintf('reading description file in repository ("%s")', $file));
|
||||
}
|
||||
}
|
||||
|
||||
if (false === $exists) {
|
||||
return static::DEFAULT_DESCRIPTION;
|
||||
}
|
||||
|
||||
return file_get_contents($this->gitDir.'/description');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if repository has a custom set description.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasDescription()
|
||||
{
|
||||
return static::DEFAULT_DESCRIPTION !== $this->getDescription();
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the repository description (file description in git-directory).
|
||||
*
|
||||
* @return Repository the current repository
|
||||
*/
|
||||
public function setDescription($description)
|
||||
{
|
||||
$file = $this->gitDir.'/description';
|
||||
|
||||
if (null !== $this->logger && true === $this->debug) {
|
||||
$this->logger->debug(sprintf('change description file content to "%s" (file: %s)', $description, $file));
|
||||
}
|
||||
file_put_contents($file, $description);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This command is a facility command. You can run any command
|
||||
* directly on git repository.
|
||||
*
|
||||
* @param string $command Git command to run (checkout, branch, tag)
|
||||
* @param array $args Arguments of git command
|
||||
*
|
||||
* @return string Output of a successful process or null if execution failed and debug-mode is disabled.
|
||||
*
|
||||
* @throws RuntimeException Error while executing git command (debug-mode only)
|
||||
*/
|
||||
public function run($command, $args = array())
|
||||
{
|
||||
$process = $this->getProcess($command, $args);
|
||||
|
||||
if ($this->logger) {
|
||||
$this->logger->info(sprintf('run command: %s "%s" ', $command, implode(' ', $args)));
|
||||
$before = microtime(true);
|
||||
}
|
||||
|
||||
$process->run();
|
||||
|
||||
$output = $process->getOutput();
|
||||
|
||||
if ($this->logger && $this->debug) {
|
||||
$duration = microtime(true) - $before;
|
||||
$this->logger->debug(sprintf('last command (%s) duration: %sms', $command, sprintf('%.2f', $duration * 1000)));
|
||||
$this->logger->debug(sprintf('last command (%s) return code: %s', $command, $process->getExitCode()));
|
||||
$this->logger->debug(sprintf('last command (%s) output: %s', $command, $output));
|
||||
}
|
||||
|
||||
if (!$process->isSuccessful()) {
|
||||
$error = sprintf("error while running %s\n output: \"%s\"", $command, $process->getErrorOutput());
|
||||
|
||||
if ($this->logger) {
|
||||
$this->logger->error($error);
|
||||
}
|
||||
|
||||
if ($this->debug) {
|
||||
throw new ProcessException($process);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set repository logger.
|
||||
*
|
||||
* @param LoggerInterface $logger A logger
|
||||
*
|
||||
* @return Repository The current repository
|
||||
*/
|
||||
public function setLogger(LoggerInterface $logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns repository logger.
|
||||
*
|
||||
* @return LoggerInterface the logger or null
|
||||
*/
|
||||
public function getLogger()
|
||||
{
|
||||
return $this->logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones the current repository to a new directory and return instance of new repository.
|
||||
*
|
||||
* @param string $path path to the new repository in which current repository will be cloned
|
||||
* @param bool $bare flag indicating if repository is bare or has a working-copy
|
||||
*
|
||||
* @return Repository the newly created repository
|
||||
*/
|
||||
public function cloneTo($path, $bare = true, array $options = array())
|
||||
{
|
||||
return Admin::cloneTo($path, $this->gitDir, $bare, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* This internal method is used to create a process object.
|
||||
*
|
||||
* Made private to be sure that process creation is handled through the run method.
|
||||
* run method ensures logging and debug.
|
||||
*
|
||||
* @see self::run
|
||||
*/
|
||||
private function getProcess($command, $args = array())
|
||||
{
|
||||
$base = array($this->command, '--git-dir', $this->gitDir);
|
||||
|
||||
if ($this->workingDir) {
|
||||
$base = array_merge($base, array('--work-tree', $this->workingDir));
|
||||
}
|
||||
|
||||
$base[] = $command;
|
||||
|
||||
$commandlineArguments = array_merge($base, $args);
|
||||
$commandline = $this->normalizeCommandlineArguments($commandlineArguments);
|
||||
|
||||
$process = new Process($commandline);
|
||||
$process->setEnv($this->environmentVariables);
|
||||
$process->setTimeout($this->processTimeout);
|
||||
$process->setIdleTimeout($this->processTimeout);
|
||||
|
||||
return $process;
|
||||
}
|
||||
|
||||
/**
|
||||
* This internal helper method is used to convert an array of commandline
|
||||
* arguments to an escaped commandline string for older versions of the
|
||||
* Symfony Process component.
|
||||
*
|
||||
* It acts as a backward compatible layer for Symfony Process < 3.3.
|
||||
*
|
||||
* @param array $arguments a list of command line arguments
|
||||
*
|
||||
* @return string|array a single escaped string (< 4.0) or a raw array of
|
||||
* the arguments passed in (4.0+)
|
||||
*
|
||||
* @see Process::escapeArgument()
|
||||
* @see ProcessUtils::escapeArgument()
|
||||
*/
|
||||
private function normalizeCommandlineArguments(array $arguments)
|
||||
{
|
||||
// From version 4.0 and onwards, the Process accepts an array of
|
||||
// arguments, and escaping is taken care of automatically.
|
||||
if (!class_exists('Symfony\Component\Process\ProcessBuilder')) {
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
// For version < 3.3, the Process only accepts a simple string
|
||||
// as commandline, and escaping has to happen manually.
|
||||
$commandline = implode(' ', array_map(
|
||||
'Symfony\Component\Process\ProcessUtils::escapeArgument',
|
||||
$arguments
|
||||
));
|
||||
|
||||
return $commandline;
|
||||
}
|
||||
}
|
68
vendor/gitonomy/gitlib/src/Gitonomy/Git/Revision.php
vendored
Normal file
68
vendor/gitonomy/gitlib/src/Gitonomy/Git/Revision.php
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git;
|
||||
|
||||
/**
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*/
|
||||
class Revision
|
||||
{
|
||||
/**
|
||||
* @var Repository
|
||||
*/
|
||||
protected $repository;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $revision;
|
||||
|
||||
public function __construct(Repository $repository, $revision)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
$this->revision = $revision;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Log
|
||||
*/
|
||||
public function getLog($paths = null, $offset = null, $limit = null)
|
||||
{
|
||||
return $this->repository->getLog($this, $paths, $offset, $limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last modification date of the reference.
|
||||
*
|
||||
* @return Commit
|
||||
*/
|
||||
public function getCommit()
|
||||
{
|
||||
return $this->getLog()->getSingleCommit();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRevision()
|
||||
{
|
||||
return $this->revision;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Repository
|
||||
*/
|
||||
public function getRepository()
|
||||
{
|
||||
return $this->repository;
|
||||
}
|
||||
}
|
72
vendor/gitonomy/gitlib/src/Gitonomy/Git/RevisionList.php
vendored
Normal file
72
vendor/gitonomy/gitlib/src/Gitonomy/Git/RevisionList.php
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git;
|
||||
|
||||
/**
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*/
|
||||
class RevisionList implements \IteratorAggregate, \Countable
|
||||
{
|
||||
protected $revisions;
|
||||
|
||||
/**
|
||||
* Constructs a revision list from a variety of types.
|
||||
*
|
||||
* @param mixed $revisions can be a string, an array of strings or an array of Revision, Branch, Tag, Commit
|
||||
*/
|
||||
public function __construct(Repository $repository, $revisions)
|
||||
{
|
||||
if (is_string($revisions)) {
|
||||
$revisions = array($repository->getRevision($revisions));
|
||||
} elseif ($revisions instanceof Revision) {
|
||||
$revisions = array($revisions);
|
||||
} elseif (!is_array($revisions)) {
|
||||
throw new \InvalidArgumentException(sprintf('Expected a string, a Revision or an array, got a "%s".', is_object($revisions) ? get_class($revisions) : gettype($revisions)));
|
||||
}
|
||||
|
||||
if (count($revisions) == 0) {
|
||||
throw new \InvalidArgumentException(sprintf('Empty revision list not allowed'));
|
||||
}
|
||||
|
||||
foreach ($revisions as $i => $revision) {
|
||||
if (is_string($revision)) {
|
||||
$revisions[$i] = new Revision($repository, $revision);
|
||||
} elseif (!$revision instanceof Revision) {
|
||||
throw new \InvalidArgumentException(sprintf('Expected a "Revision", got a "%s".', is_object($revision) ? get_class($revision) : gettype($revision)));
|
||||
}
|
||||
}
|
||||
|
||||
$this->revisions = $revisions;
|
||||
}
|
||||
|
||||
public function getAll()
|
||||
{
|
||||
return $this->revisions;
|
||||
}
|
||||
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->revisions);
|
||||
}
|
||||
|
||||
public function count()
|
||||
{
|
||||
return count($this->revisions);
|
||||
}
|
||||
|
||||
public function getAsTextArray()
|
||||
{
|
||||
return array_map(function ($revision) {
|
||||
return $revision->getRevision();
|
||||
}, $this->revisions);
|
||||
}
|
||||
}
|
107
vendor/gitonomy/gitlib/src/Gitonomy/Git/Tree.php
vendored
Normal file
107
vendor/gitonomy/gitlib/src/Gitonomy/Git/Tree.php
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git;
|
||||
|
||||
use Gitonomy\Git\Exception\InvalidArgumentException;
|
||||
use Gitonomy\Git\Exception\UnexpectedValueException;
|
||||
|
||||
/**
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*/
|
||||
class Tree
|
||||
{
|
||||
protected $repository;
|
||||
protected $hash;
|
||||
protected $isInitialized = false;
|
||||
protected $entries;
|
||||
|
||||
public function __construct(Repository $repository, $hash)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
$this->hash = $hash;
|
||||
}
|
||||
|
||||
public function getHash()
|
||||
{
|
||||
return $this->hash;
|
||||
}
|
||||
|
||||
protected function initialize()
|
||||
{
|
||||
if (true === $this->isInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
$output = $this->repository->run('cat-file', array('-p', $this->hash));
|
||||
$parser = new Parser\TreeParser();
|
||||
$parser->parse($output);
|
||||
|
||||
$this->entries = array();
|
||||
|
||||
foreach ($parser->entries as $entry) {
|
||||
list($mode, $type, $hash, $name) = $entry;
|
||||
if ($type == 'blob') {
|
||||
$this->entries[$name] = array($mode, $this->repository->getBlob($hash));
|
||||
} elseif ($type == 'tree') {
|
||||
$this->entries[$name] = array($mode, $this->repository->getTree($hash));
|
||||
} else {
|
||||
$this->entries[$name] = array($mode, new CommitReference($hash));
|
||||
}
|
||||
}
|
||||
|
||||
$this->isInitialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array An associative array name => $object
|
||||
*/
|
||||
public function getEntries()
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
return $this->entries;
|
||||
}
|
||||
|
||||
public function getEntry($name)
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
if (!isset($this->entries[$name])) {
|
||||
throw new InvalidArgumentException('No entry '.$name);
|
||||
}
|
||||
|
||||
return $this->entries[$name][1];
|
||||
}
|
||||
|
||||
public function resolvePath($path)
|
||||
{
|
||||
if ($path == '') {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$path = preg_replace('#^/#', '', $path);
|
||||
|
||||
$segments = explode('/', $path);
|
||||
$element = $this;
|
||||
foreach ($segments as $segment) {
|
||||
if ($element instanceof self) {
|
||||
$element = $element->getEntry($segment);
|
||||
} elseif ($entry instanceof Blob) {
|
||||
throw new InvalidArgumentException('Unresolvable path');
|
||||
} else {
|
||||
throw new UnexpectedValueException('Unknow type of element');
|
||||
}
|
||||
}
|
||||
|
||||
return $element;
|
||||
}
|
||||
}
|
56
vendor/gitonomy/gitlib/src/Gitonomy/Git/Util/StringHelper.php
vendored
Normal file
56
vendor/gitonomy/gitlib/src/Gitonomy/Git/Util/StringHelper.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Util;
|
||||
|
||||
/**
|
||||
* Helper class to support language particularity.
|
||||
*
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*/
|
||||
class StringHelper
|
||||
{
|
||||
private static $encoding = 'utf-8';
|
||||
|
||||
public static function getEncoding()
|
||||
{
|
||||
return self::$encoding;
|
||||
}
|
||||
|
||||
public static function setEncoding($encoding)
|
||||
{
|
||||
self::$encoding = $encoding;
|
||||
}
|
||||
|
||||
public static function strlen($string)
|
||||
{
|
||||
return function_exists('mb_strlen') ? mb_strlen($string, self::$encoding) : strlen($string);
|
||||
}
|
||||
|
||||
public static function substr($string, $start, $length = false)
|
||||
{
|
||||
if (false === $length) {
|
||||
$length = self::strlen($string);
|
||||
}
|
||||
|
||||
return function_exists('mb_substr') ? mb_substr($string, $start, $length, self::$encoding) : substr($string, $start, $length);
|
||||
}
|
||||
|
||||
public static function strpos($haystack, $needle, $offset = 0)
|
||||
{
|
||||
return function_exists('mb_strpos') ? mb_strpos($haystack, $needle, $offset, self::$encoding) : strpos($haystack, $needle, $offset);
|
||||
}
|
||||
|
||||
public static function strrpos($haystack, $needle, $offset = 0)
|
||||
{
|
||||
return function_exists('mb_strrpos') ? mb_strrpos($haystack, $needle, $offset, self::$encoding) : strrpos($haystack, $needle, $offset);
|
||||
}
|
||||
}
|
96
vendor/gitonomy/gitlib/src/Gitonomy/Git/WorkingCopy.php
vendored
Normal file
96
vendor/gitonomy/gitlib/src/Gitonomy/Git/WorkingCopy.php
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git;
|
||||
|
||||
use Gitonomy\Git\Diff\Diff;
|
||||
use Gitonomy\Git\Exception\InvalidArgumentException;
|
||||
use Gitonomy\Git\Exception\LogicException;
|
||||
|
||||
/**
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*/
|
||||
class WorkingCopy
|
||||
{
|
||||
/**
|
||||
* @var Repository
|
||||
*/
|
||||
protected $repository;
|
||||
|
||||
public function __construct(Repository $repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
|
||||
if ($this->repository->isBare()) {
|
||||
throw new LogicException('Can\'t create a working copy on a bare repository');
|
||||
}
|
||||
}
|
||||
|
||||
public function getStatus()
|
||||
{
|
||||
return WorkingStatus::parseOutput();
|
||||
}
|
||||
|
||||
public function getUntrackedFiles()
|
||||
{
|
||||
$lines = explode("\0", $this->run('status', array('--porcelain', '--untracked-files=all', '-z')));
|
||||
$lines = array_filter($lines, function ($l) { return substr($l, 0, 3) === '?? '; });
|
||||
$lines = array_map(function ($l) { return substr($l, 3); }, $lines);
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
public function getDiffPending()
|
||||
{
|
||||
$diff = Diff::parse($this->run('diff', array('-r', '-p', '-m', '-M', '--full-index')));
|
||||
$diff->setRepository($this->repository);
|
||||
|
||||
return $diff;
|
||||
}
|
||||
|
||||
public function getDiffStaged()
|
||||
{
|
||||
$diff = Diff::parse($this->run('diff', array('-r', '-p', '-m', '-M', '--full-index', '--staged')));
|
||||
$diff->setRepository($this->repository);
|
||||
|
||||
return $diff;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WorkingCopy
|
||||
*/
|
||||
public function checkout($revision, $branch = null)
|
||||
{
|
||||
$args = array();
|
||||
if ($revision instanceof Commit) {
|
||||
$args[] = $revision->getHash();
|
||||
} elseif ($revision instanceof Reference) {
|
||||
$args[] = $revision->getFullname();
|
||||
} elseif (is_string($revision)) {
|
||||
$args[] = $revision;
|
||||
} else {
|
||||
throw new InvalidArgumentException(sprintf('Unknown type "%s"', gettype($revision)));
|
||||
}
|
||||
|
||||
if (null !== $branch) {
|
||||
$args = array_merge($args, array('-b', $branch));
|
||||
}
|
||||
|
||||
$this->run('checkout', $args);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function run($command, array $args = array())
|
||||
{
|
||||
return $this->repository->run($command, $args);
|
||||
}
|
||||
}
|
74
vendor/gitonomy/gitlib/test-git-versions.sh
vendored
Executable file
74
vendor/gitonomy/gitlib/test-git-versions.sh
vendored
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
URL="git@github.com:git/git.git"
|
||||
VERSIONS="v1.6.3 v1.6.6 v1.7.1 v1.7.5 v1.7.9 v1.8.1"
|
||||
DIRNAME="git-builds"
|
||||
|
||||
if [ ! -d "$DIRNAME" ]; then
|
||||
mkdir - "$DIRNAME"
|
||||
fi
|
||||
|
||||
cd "$DIRNAME"
|
||||
|
||||
# remote repository
|
||||
if [ -d cache ]; then
|
||||
echo "- update from github..."
|
||||
cd cache
|
||||
git fetch -q
|
||||
cd ..
|
||||
else
|
||||
echo "- clone from github..."
|
||||
git clone "$URL" cache -q
|
||||
fi
|
||||
|
||||
# build
|
||||
for VERSION in $VERSIONS; do
|
||||
|
||||
echo "- build $VERSION"
|
||||
LOGFILE="build.$VERSION.log"
|
||||
LOCKFILE="build.$VERSION.lock"
|
||||
|
||||
if [ -f "$LOCKFILE" ]; then
|
||||
echo " - lock present, destroy build..."
|
||||
rm -rf "$VERSION" "build.$VERSION.log"
|
||||
fi
|
||||
|
||||
if [ -d "$VERSION" ]; then
|
||||
echo " - already built, skipping..."
|
||||
continue
|
||||
fi
|
||||
|
||||
touch "$LOCKFILE"
|
||||
|
||||
echo " - log: $LOGFILE"
|
||||
touch "$LOGFILE"
|
||||
mkdir "$VERSION"
|
||||
echo " - clone repository"
|
||||
git clone -s cache "$VERSION/source" -q
|
||||
echo " - checkout version"
|
||||
cd "$VERSION/source"
|
||||
git checkout "$VERSION" -q
|
||||
|
||||
mkdir ../build
|
||||
PREFIX="`readlink -f ../build`"
|
||||
|
||||
echo " - build..."
|
||||
autoconf >> "../../$LOGFILE" 2>&1
|
||||
./configure --prefix="$PREFIX" >> "../../$LOGFILE" 2>&1
|
||||
make all >> "../../$LOGFILE" 2>&1
|
||||
make install >> "../../$LOGFILE" 2>&1
|
||||
echo " - build ok"
|
||||
cd ../..
|
||||
rm "$LOCKFILE"
|
||||
done
|
||||
cd ..
|
||||
|
||||
# test
|
||||
echo ""
|
||||
for VERSION in $VERSIONS; do
|
||||
echo "- test $VERSION"
|
||||
GIT_COMMAND="`readlink -f $DIRNAME/$VERSION/build/bin/git`"
|
||||
echo " - command: $GIT_COMMAND"
|
||||
GIT_COMMAND="$GIT_COMMAND" phpunit || true
|
||||
done
|
149
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/AbstractTest.php
vendored
Normal file
149
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/AbstractTest.php
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Tests;
|
||||
|
||||
use Gitonomy\Git\Admin;
|
||||
use Gitonomy\Git\Repository;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
abstract class AbstractTest extends TestCase
|
||||
{
|
||||
const REPOSITORY_URL = 'http://github.com/gitonomy/foobar.git';
|
||||
|
||||
const LONGFILE_COMMIT = '4f17752acc9b7c54ba679291bf24cb7d354f0f4f';
|
||||
const BEFORE_LONGFILE_COMMIT = 'e0ec50e2af75fa35485513f60b2e658e245227e9';
|
||||
const LONGMESSAGE_COMMIT = '3febd664b6886344a9b32d70657687ea4b1b4fab';
|
||||
const INITIAL_COMMIT = '74acd054c8ec873ae6be044041d3a85a4f890ba5';
|
||||
const MERGE_COMMIT = '2f5b9d0a4e6e7173d7816e417805709c708674f8';
|
||||
const ENCODING_COMMIT = '779420b9b936f18a0b6579e1499a85b14270802e';
|
||||
const SIGNED_COMMIT = 'e1a83f16ed61ae3807e5652c7ef894692c813513';
|
||||
|
||||
/**
|
||||
* Local clone of remote URL. Avoids network call on each test.
|
||||
*/
|
||||
private static $localRepository;
|
||||
|
||||
/**
|
||||
* Creates an empty git repository and returns instance.
|
||||
*
|
||||
* @return Repository
|
||||
*/
|
||||
public static function createEmptyRepository($bare = true)
|
||||
{
|
||||
$dir = self::createTempDir();
|
||||
$repository = Admin::init($dir, $bare, self::getOptions());
|
||||
self::registerDeletion($repository);
|
||||
|
||||
return $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used as data provider to get bare/not-bare repositories.
|
||||
*/
|
||||
public static function provideFoobar()
|
||||
{
|
||||
return array(
|
||||
array(self::createFoobarRepository()),
|
||||
array(self::createFoobarRepository(false)),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used as data provider to get bare/not-bare repositories.
|
||||
*/
|
||||
public static function provideEmpty()
|
||||
{
|
||||
return array(
|
||||
array(self::createEmptyRepository()),
|
||||
array(self::createEmptyRepository(false)),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fixture test repository.
|
||||
*
|
||||
* @return Repository
|
||||
*/
|
||||
public static function createFoobarRepository($bare = true)
|
||||
{
|
||||
if (null === self::$localRepository) {
|
||||
self::$localRepository = Admin::cloneTo(self::createTempDir(), self::REPOSITORY_URL, $bare, self::getOptions());
|
||||
}
|
||||
|
||||
$repository = self::$localRepository->cloneTo(self::createTempDir(), $bare, self::getOptions());
|
||||
self::registerDeletion($repository);
|
||||
|
||||
return $repository;
|
||||
}
|
||||
|
||||
public static function registerDeletion(Repository $repository)
|
||||
{
|
||||
register_shutdown_function(function () use ($repository) {
|
||||
if ($repository->getWorkingDir()) {
|
||||
$dir = $repository->getWorkingDir();
|
||||
} else {
|
||||
$dir = $repository->getGitDir();
|
||||
}
|
||||
AbstractTest::deleteDir($dir);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Created an empty directory and return path to it.
|
||||
*
|
||||
* @return string a fullpath
|
||||
*/
|
||||
public static function createTempDir()
|
||||
{
|
||||
$tmpDir = tempnam(sys_get_temp_dir(), 'gitlib_');
|
||||
unlink($tmpDir);
|
||||
mkdir($tmpDir);
|
||||
|
||||
return $tmpDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a directory recursively.
|
||||
*
|
||||
* @param string $dir directory to delete
|
||||
*/
|
||||
public static function deleteDir($dir)
|
||||
{
|
||||
$iterator = new \RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS);
|
||||
$iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::CHILD_FIRST);
|
||||
foreach ($iterator as $file) {
|
||||
if (!is_link($file)) {
|
||||
chmod($file, 0777);
|
||||
}
|
||||
if (is_dir($file)) {
|
||||
rmdir($file);
|
||||
} else {
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
|
||||
chmod($dir, 0777);
|
||||
rmdir($dir);
|
||||
}
|
||||
|
||||
protected static function getOptions()
|
||||
{
|
||||
$command = isset($_SERVER['GIT_COMMAND']) ? $_SERVER['GIT_COMMAND'] : 'git';
|
||||
$envs = isset($_SERVER['GIT_ENVS']) ? (array) $_SERVER['GIT_ENVS'] : array();
|
||||
|
||||
return array(
|
||||
'command' => $command,
|
||||
'environment_variables' => $envs,
|
||||
'process_timeout' => 60,
|
||||
);
|
||||
}
|
||||
}
|
177
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/AdminTest.php
vendored
Normal file
177
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/AdminTest.php
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Tests;
|
||||
|
||||
use Gitonomy\Git\Admin;
|
||||
use Gitonomy\Git\Reference\Branch;
|
||||
use Gitonomy\Git\Repository;
|
||||
|
||||
class AdminTest extends AbstractTest
|
||||
{
|
||||
private $tmpDir;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->tmpDir = self::createTempDir();
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->deleteDir(self::createTempDir());
|
||||
}
|
||||
|
||||
public function testBare()
|
||||
{
|
||||
$repository = Admin::init($this->tmpDir, true, self::getOptions());
|
||||
|
||||
$objectDir = $this->tmpDir.'/objects';
|
||||
|
||||
$this->assertTrue($repository->isBare(), 'Repository is bare');
|
||||
$this->assertTrue(is_dir($objectDir), 'objects/ folder is present');
|
||||
$this->assertTrue($repository instanceof Repository, 'Admin::init returns a repository');
|
||||
$this->assertEquals($this->tmpDir, $repository->getGitDir(), 'The folder passed as argument is git dir');
|
||||
$this->assertNull($repository->getWorkingDir(), 'No working dir in bare repository');
|
||||
}
|
||||
|
||||
public function testNotBare()
|
||||
{
|
||||
$repository = Admin::init($this->tmpDir, false, self::getOptions());
|
||||
|
||||
$objectDir = $this->tmpDir.'/.git/objects';
|
||||
|
||||
$this->assertFalse($repository->isBare(), 'Repository is not bare');
|
||||
$this->assertTrue(is_dir($objectDir), 'objects/ folder is present');
|
||||
$this->assertTrue($repository instanceof Repository, 'Admin::init returns a repository');
|
||||
$this->assertEquals($this->tmpDir.'/.git', $repository->getGitDir(), 'git dir as subfolder of argument');
|
||||
$this->assertEquals($this->tmpDir, $repository->getWorkingDir(), 'working dir present in bare repository');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testClone($repository)
|
||||
{
|
||||
$newDir = self::createTempDir();
|
||||
$new = $repository->cloneTo($newDir, $repository->isBare(), self::getOptions());
|
||||
self::registerDeletion($new);
|
||||
|
||||
$newRefs = array_keys($new->getReferences()->getAll());
|
||||
|
||||
$this->assertTrue(in_array('refs/heads/master', $newRefs));
|
||||
$this->assertTrue(in_array('refs/tags/0.1', $newRefs));
|
||||
|
||||
if ($repository->isBare()) {
|
||||
$this->assertEquals($newDir, $new->getGitDir());
|
||||
$this->assertTrue(in_array('refs/heads/new-feature', $newRefs));
|
||||
} else {
|
||||
$this->assertEquals($newDir.'/.git', $new->getGitDir());
|
||||
$this->assertEquals($newDir, $new->getWorkingDir());
|
||||
}
|
||||
}
|
||||
|
||||
public function testCloneBranchBare()
|
||||
{
|
||||
//we can't use AbstractText::createFoobarRepository()
|
||||
//because it does not clone other branches than "master"
|
||||
//so we test it directly against the remote repository
|
||||
|
||||
$newDir = self::createTempDir();
|
||||
$new = Admin::cloneBranchTo($newDir, self::REPOSITORY_URL, 'new-feature');
|
||||
self::registerDeletion($new);
|
||||
|
||||
$head = $new->getHead();
|
||||
$this->assertTrue($head instanceof Branch, 'HEAD is a branch');
|
||||
$this->assertEquals('new-feature', $head->getName(), 'HEAD is branch new-feature');
|
||||
}
|
||||
|
||||
public function testCloneBranchNotBare()
|
||||
{
|
||||
//we can't use AbstractText::createFoobarRepository()
|
||||
//because it does not clone other branches than "master"
|
||||
//so we test it directly against remote repository
|
||||
|
||||
$newDir = self::createTempDir();
|
||||
$new = Admin::cloneBranchTo($newDir, self::REPOSITORY_URL, 'new-feature', false);
|
||||
self::registerDeletion($new);
|
||||
|
||||
$head = $new->getHead();
|
||||
$this->assertTrue($head instanceof Branch, 'HEAD is a branch');
|
||||
$this->assertEquals('new-feature', $head->getName(), 'HEAD is branch new-feature');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testMirror($repository)
|
||||
{
|
||||
$newDir = self::createTempDir();
|
||||
$new = Admin::mirrorTo($newDir, $repository->getGitDir(), self::getOptions());
|
||||
self::registerDeletion($new);
|
||||
|
||||
$newRefs = array_keys($new->getReferences()->getAll());
|
||||
|
||||
$this->assertTrue(in_array('refs/heads/master', $newRefs));
|
||||
$this->assertTrue(in_array('refs/tags/0.1', $newRefs));
|
||||
$this->assertEquals($newDir, $new->getGitDir());
|
||||
|
||||
if ($repository->isBare()) {
|
||||
$this->assertTrue(in_array('refs/heads/new-feature', $newRefs));
|
||||
} else {
|
||||
$this->assertTrue(in_array('refs/remotes/origin/new-feature', $newRefs));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testCheckValidRepository($repository)
|
||||
{
|
||||
$url = $repository->getGitDir();
|
||||
$this->assertTrue(Admin::isValidRepository($url));
|
||||
}
|
||||
|
||||
public function testCheckInvalidRepository()
|
||||
{
|
||||
$url = $this->tmpDir.'/invalid.git';
|
||||
mkdir($url);
|
||||
|
||||
$this->assertFalse(Admin::isValidRepository($url));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException RuntimeException
|
||||
*/
|
||||
public function testExistingFile()
|
||||
{
|
||||
$file = $this->tmpDir.'/test';
|
||||
touch($file);
|
||||
|
||||
Admin::init($file, true, self::getOptions());
|
||||
}
|
||||
|
||||
public function testCloneRepository()
|
||||
{
|
||||
$newDir = self::createTempDir();
|
||||
$args = array();
|
||||
|
||||
$new = Admin::cloneRepository($newDir, self::REPOSITORY_URL, $args, self::getOptions());
|
||||
self::registerDeletion($new);
|
||||
|
||||
$newRefs = array_keys($new->getReferences()->getAll());
|
||||
|
||||
$this->assertTrue(in_array('refs/heads/master', $newRefs));
|
||||
$this->assertTrue(in_array('refs/tags/0.1', $newRefs));
|
||||
|
||||
$this->assertEquals($newDir.'/.git', $new->getGitDir());
|
||||
$this->assertEquals($newDir, $new->getWorkingDir());
|
||||
}
|
||||
}
|
43
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/BlameTest.php
vendored
Normal file
43
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/BlameTest.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Tests;
|
||||
|
||||
class BlameTest extends AbstractTest
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testBlame($repository)
|
||||
{
|
||||
$blame = $repository->getBlame(self::LONGFILE_COMMIT, 'README.md');
|
||||
|
||||
$this->assertCount(7, $blame);
|
||||
|
||||
$this->assertEquals('alice', $blame->getLine(1)->getCommit()->getAuthorName());
|
||||
$this->assertEquals(self::INITIAL_COMMIT, $blame->getLine(1)->getCommit()->getHash());
|
||||
|
||||
$this->assertEquals('alice', $blame->getLine(5)->getCommit()->getAuthorName());
|
||||
$this->assertNotEquals(self::INITIAL_COMMIT, $blame->getLine(5)->getCommit()->getHash());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGroupedBlame($repository)
|
||||
{
|
||||
$blame = $repository->getBlame(self::LONGFILE_COMMIT, 'README.md')->getGroupedLines();
|
||||
|
||||
$this->assertCount(3, $blame);
|
||||
|
||||
$this->assertEquals(self::INITIAL_COMMIT, $blame[0][0]->getHash());
|
||||
}
|
||||
}
|
69
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/BlobTest.php
vendored
Normal file
69
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/BlobTest.php
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Tests;
|
||||
|
||||
class BlobTest extends AbstractTest
|
||||
{
|
||||
const README_FRAGMENT = 'Foo Bar project';
|
||||
|
||||
public function getReadmeBlob($repository)
|
||||
{
|
||||
return $repository->getCommit(self::LONGFILE_COMMIT)->getTree()->resolvePath('README.md');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetContent($repository)
|
||||
{
|
||||
$blob = $this->getReadmeBlob($repository);
|
||||
|
||||
$this->assertContains(self::README_FRAGMENT, $blob->getContent());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
* @expectedException RuntimeException
|
||||
*/
|
||||
public function testNotExisting($repository)
|
||||
{
|
||||
$blob = $repository->getBlob('foobar');
|
||||
$blob->getContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetMimetype($repository)
|
||||
{
|
||||
$blob = $this->getReadmeBlob($repository);
|
||||
$this->assertRegexp('#text/plain#', $blob->getMimetype());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testIsText($repository)
|
||||
{
|
||||
$blob = $this->getReadmeBlob($repository);
|
||||
$this->assertTrue($blob->isText());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testIsBinary($repository)
|
||||
{
|
||||
$blob = $this->getReadmeBlob($repository);
|
||||
$this->assertFalse($blob->isBinary());
|
||||
}
|
||||
}
|
301
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/CommitTest.php
vendored
Normal file
301
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/CommitTest.php
vendored
Normal file
@@ -0,0 +1,301 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Tests;
|
||||
|
||||
use Gitonomy\Git\Commit;
|
||||
use Gitonomy\Git\Diff\Diff;
|
||||
|
||||
class CommitTest extends AbstractTest
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetDiff($repository)
|
||||
{
|
||||
$commit = $repository->getCommit(self::LONGFILE_COMMIT);
|
||||
|
||||
$diff = $commit->getDiff();
|
||||
|
||||
$this->assertTrue($diff instanceof Diff, 'getDiff() returns a Diff object');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetHash($repository)
|
||||
{
|
||||
$commit = $repository->getCommit(self::LONGFILE_COMMIT);
|
||||
|
||||
$this->assertEquals(self::LONGFILE_COMMIT, $commit->getHash());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*
|
||||
* @expectedException Gitonomy\Git\Exception\ReferenceNotFoundException
|
||||
* @expectedExceptionMessage Reference not found: "that-hash-doest-not-exists"
|
||||
*/
|
||||
public function testInvalideHashThrowException($repository)
|
||||
{
|
||||
$commit = new Commit($repository, 'that-hash-doest-not-exists');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetShortHash($repository)
|
||||
{
|
||||
$commit = $repository->getCommit(self::LONGFILE_COMMIT);
|
||||
|
||||
$this->assertEquals('4f17752', $commit->getShortHash(), 'Short hash');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetParentHashes_WithNoParent($repository)
|
||||
{
|
||||
$commit = $repository->getCommit(self::INITIAL_COMMIT);
|
||||
|
||||
$this->assertEquals(0, count($commit->getParentHashes()), 'No parent on initial commit');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetParentHashes_WithOneParent($repository)
|
||||
{
|
||||
$commit = $repository->getCommit(self::LONGFILE_COMMIT);
|
||||
$parents = $commit->getParentHashes();
|
||||
|
||||
$this->assertEquals(1, count($parents), 'One parent found');
|
||||
$this->assertEquals(self::BEFORE_LONGFILE_COMMIT, $parents[0], 'Parent hash is correct');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetParents_WithOneParent($repository)
|
||||
{
|
||||
$commit = $repository->getCommit(self::LONGFILE_COMMIT);
|
||||
$parents = $commit->getParents();
|
||||
|
||||
$this->assertEquals(1, count($parents), 'One parent found');
|
||||
$this->assertTrue($parents[0] instanceof Commit, 'First parent is a Commit object');
|
||||
$this->assertEquals(self::BEFORE_LONGFILE_COMMIT, $parents[0]->getHash(), "First parents's hash is correct");
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetTreeHash($repository)
|
||||
{
|
||||
$commit = $repository->getCommit(self::LONGFILE_COMMIT);
|
||||
|
||||
$this->assertEquals('b06890c7b10904979d2f69613c2ccda30aafe262', $commit->getTreeHash(), 'Tree hash is correct');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetTree($repository)
|
||||
{
|
||||
$commit = $repository->getCommit(self::LONGFILE_COMMIT);
|
||||
|
||||
$this->assertInstanceOf('Gitonomy\Git\Tree', $commit->getTree(), 'Tree is a tree');
|
||||
$this->assertEquals('b06890c7b10904979d2f69613c2ccda30aafe262', $commit->getTree()->getHash(), 'Tree hash is correct');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetAuthorName($repository)
|
||||
{
|
||||
$commit = $repository->getCommit(self::LONGFILE_COMMIT);
|
||||
|
||||
$this->assertEquals('alice', $commit->getAuthorName(), 'Author name');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetAuthorEmail($repository)
|
||||
{
|
||||
$commit = $repository->getCommit(self::LONGFILE_COMMIT);
|
||||
|
||||
$this->assertEquals('alice@example.org', $commit->getAuthorEmail(), 'Author email');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetAuthorDate($repository)
|
||||
{
|
||||
$commit = $repository->getCommit(self::LONGFILE_COMMIT);
|
||||
|
||||
$this->assertEquals('2012-12-31 14:21:03', $commit->getAuthorDate()->format('Y-m-d H:i:s'), 'Author date');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetCommitterName($repository)
|
||||
{
|
||||
$commit = $repository->getCommit(self::LONGFILE_COMMIT);
|
||||
|
||||
$this->assertEquals('alice', $commit->getCommitterName(), 'Committer name');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetCommitterEmail($repository)
|
||||
{
|
||||
$commit = $repository->getCommit(self::LONGFILE_COMMIT);
|
||||
|
||||
$this->assertEquals('alice@example.org', $commit->getCommitterEmail(), 'Committer email');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetCommitterDate($repository)
|
||||
{
|
||||
$commit = $repository->getCommit(self::LONGFILE_COMMIT);
|
||||
|
||||
$this->assertEquals('2012-12-31 14:21:03', $commit->getCommitterDate()->format('Y-m-d H:i:s'), 'Committer date');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetMessage($repository)
|
||||
{
|
||||
$commit = $repository->getCommit(self::LONGFILE_COMMIT);
|
||||
|
||||
$this->assertEquals('add a long file'."\n", $commit->getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* This test ensures that GPG signed commits does not break the reading of a commit
|
||||
* message.
|
||||
*
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetSignedMessage($repository)
|
||||
{
|
||||
$commit = $repository->getCommit(self::SIGNED_COMMIT);
|
||||
$this->assertEquals('signed commit'."\n", $commit->getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetShortMessage($repository)
|
||||
{
|
||||
// tests with a multi-line message
|
||||
$commit = $repository->getCommit(self::LONGMESSAGE_COMMIT);
|
||||
|
||||
$this->assertEquals('Fixed perm...', $commit->getShortMessage(10));
|
||||
$this->assertEquals('Fixed perm!!!', $commit->getShortMessage(10, false, '!!!'));
|
||||
$this->assertEquals('Fixed permissions!!!', $commit->getShortMessage(10, true, '!!!'));
|
||||
|
||||
// tests with a single-line message
|
||||
$commit = $repository->getCommit(self::INITIAL_COMMIT);
|
||||
|
||||
$this->assertEquals('Add README', $commit->getShortMessage(20));
|
||||
$this->assertEquals('A', $commit->getShortMessage(1, false, ''));
|
||||
$this->assertEquals('Add!!!', $commit->getShortMessage(1, true, '!!!'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetBodyMessage($repository)
|
||||
{
|
||||
$commit = $repository->getCommit(self::LONGMESSAGE_COMMIT);
|
||||
$message = <<<EOL
|
||||
If you want to know everything,
|
||||
I ran something like `chmox +x test.sh`
|
||||
|
||||
Hello and good bye.
|
||||
|
||||
EOL;
|
||||
|
||||
$this->assertEquals($message, $commit->getBodyMessage());
|
||||
|
||||
$commit = $repository->getCommit(self::INITIAL_COMMIT);
|
||||
|
||||
$this->assertEquals('', $commit->getBodyMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetIncludingBranchesException($repository)
|
||||
{
|
||||
$commit = $repository->getCommit(self::INITIAL_COMMIT);
|
||||
|
||||
$commit->getIncludingBranches(false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetIncludingBranches($repository)
|
||||
{
|
||||
$commit = $repository->getCommit(self::INITIAL_COMMIT);
|
||||
|
||||
$branches = $commit->getIncludingBranches(true, false);
|
||||
$this->assertCount(count($repository->getReferences()->getLocalBranches()), $branches);
|
||||
|
||||
$branches = $commit->getIncludingBranches(true, true);
|
||||
$this->assertCount(count($repository->getReferences()->getBranches()), $branches);
|
||||
|
||||
$branches = $commit->getIncludingBranches(false, true);
|
||||
$this->assertCount(count($repository->getReferences()->getRemoteBranches()), $branches);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetLastModification($repository)
|
||||
{
|
||||
$commit = $repository->getCommit(self::LONGFILE_COMMIT);
|
||||
|
||||
$lastModification = $commit->getLastModification('image.jpg');
|
||||
|
||||
$this->assertTrue($lastModification instanceof Commit, 'Last modification is a Commit object');
|
||||
$this->assertEquals(self::BEFORE_LONGFILE_COMMIT, $lastModification->getHash(), 'Last modification is current commit');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testMergeCommit($repository)
|
||||
{
|
||||
$commit = $repository->getCommit(self::MERGE_COMMIT);
|
||||
|
||||
$this->assertEquals("Merge branch 'authors'", $commit->getSubjectMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testEncoding($repository)
|
||||
{
|
||||
$commit = $repository->getCommit(self::ENCODING_COMMIT);
|
||||
|
||||
$this->assertEquals('contribute to AUTHORS file', $commit->getSubjectMessage());
|
||||
}
|
||||
}
|
142
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/DiffTest.php
vendored
Normal file
142
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/DiffTest.php
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Tests;
|
||||
|
||||
use Gitonomy\Git\Diff\Diff;
|
||||
|
||||
class DiffTest extends AbstractTest
|
||||
{
|
||||
const DELETE_COMMIT = '519d5693c72c925cd59205d9f11e9fa1d550028b';
|
||||
const CREATE_COMMIT = 'e6fa3c792facc06faa049a6938c84c411954deb5';
|
||||
const RENAME_COMMIT = '6640e0ef31518054847a1876328e26ee64083e0a';
|
||||
const CHANGEMODE_COMMIT = '93da965f58170f13017477b9a608657e87e23230';
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testSerialization($repository)
|
||||
{
|
||||
$data = $repository->getCommit(self::CREATE_COMMIT)->getDiff()->toArray();
|
||||
$diff = Diff::fromArray($data);
|
||||
|
||||
$this->verifyCreateCommitDiff($diff);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetFiles_Addition($repository)
|
||||
{
|
||||
$diff = $repository->getCommit(self::CREATE_COMMIT)->getDiff();
|
||||
$this->verifyCreateCommitDiff($diff);
|
||||
}
|
||||
|
||||
protected function verifyCreateCommitDiff(Diff $diff)
|
||||
{
|
||||
$files = $diff->getFiles();
|
||||
|
||||
$this->assertEquals(2, count($files), '1 file in diff');
|
||||
|
||||
$this->assertTrue($files[0]->isCreation(), 'script_A.php created');
|
||||
|
||||
$this->assertEquals(null, $files[0]->getOldName(), 'First file name is a new file');
|
||||
$this->assertEquals('script_A.php', $files[0]->getNewName(), 'First file name is script_A.php');
|
||||
$this->assertEquals(null, $files[0]->getOldMode(), 'First file mode is a new file');
|
||||
$this->assertEquals('100644', $files[0]->getNewMode(), 'First file mode is correct');
|
||||
|
||||
$this->assertEquals(1, $files[0]->getAdditions(), '1 line added');
|
||||
$this->assertEquals(0, $files[0]->getDeletions(), '0 lines deleted');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetFiles_Modification($repository)
|
||||
{
|
||||
$files = $repository->getCommit(self::BEFORE_LONGFILE_COMMIT)->getDiff()->getFiles();
|
||||
|
||||
$this->assertEquals(1, count($files), '1 files in diff');
|
||||
|
||||
$this->assertTrue($files[0]->isModification(), 'image.jpg modified');
|
||||
|
||||
$this->assertEquals('image.jpg', $files[0]->getOldName(), 'Second file name is image.jpg');
|
||||
$this->assertEquals('image.jpg', $files[0]->getNewName(), 'Second file name is image.jpg');
|
||||
$this->assertEquals('100644', $files[0]->getOldMode(), 'Second file mode is a new file');
|
||||
$this->assertEquals('100644', $files[0]->getNewMode(), 'Second file mode is correct');
|
||||
|
||||
$this->assertTrue($files[0]->isBinary(), 'binary file');
|
||||
$this->assertEquals(0, $files[0]->getAdditions(), '0 lines added');
|
||||
$this->assertEquals(0, $files[0]->getDeletions(), '0 lines deleted');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetFiles_Deletion($repository)
|
||||
{
|
||||
$files = $repository->getCommit(self::DELETE_COMMIT)->getDiff()->getFiles();
|
||||
|
||||
$this->assertEquals(1, count($files), '1 files modified');
|
||||
|
||||
$this->assertTrue($files[0]->isDeletion(), 'File deletion');
|
||||
$this->assertEquals('script_B.php', $files[0]->getOldName(), 'verify old filename');
|
||||
$this->assertEquals(1, $files[0]->getDeletions(), '1 line deleted');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetFiles_Rename($repository)
|
||||
{
|
||||
$files = $repository->getCommit(self::RENAME_COMMIT)->getDiff()->getFiles();
|
||||
|
||||
$this->assertEquals(1, count($files), '1 files modified');
|
||||
|
||||
$this->assertTrue($files[0]->isModification());
|
||||
$this->assertTrue($files[0]->isRename());
|
||||
$this->assertFalse($files[0]->isDeletion());
|
||||
$this->assertFalse($files[0]->isCreation());
|
||||
$this->assertFalse($files[0]->isChangeMode());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetFiles_Changemode($repository)
|
||||
{
|
||||
$files = $repository->getCommit(self::CHANGEMODE_COMMIT)->getDiff()->getFiles();
|
||||
|
||||
$this->assertEquals(1, count($files), '1 files modified');
|
||||
|
||||
$this->assertTrue($files[0]->isModification());
|
||||
$this->assertTrue($files[0]->isChangeMode());
|
||||
$this->assertFalse($files[0]->isDeletion());
|
||||
$this->assertFalse($files[0]->isCreation());
|
||||
$this->assertFalse($files[0]->isRename());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testDiffRangeParse($repository)
|
||||
{
|
||||
$files = $repository->getCommit(self::CREATE_COMMIT)->getDiff()->getFiles();
|
||||
|
||||
$changes = $files[0]->getChanges();
|
||||
|
||||
$this->assertEquals(0, $changes[0]->getRangeOldStart());
|
||||
$this->assertEquals(0, $changes[0]->getRangeOldCount());
|
||||
|
||||
$this->assertEquals(1, $changes[0]->getRangeNewStart());
|
||||
$this->assertEquals(0, $changes[0]->getRangeNewCount());
|
||||
}
|
||||
}
|
178
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/HooksTest.php
vendored
Normal file
178
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/HooksTest.php
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Tests;
|
||||
|
||||
class HooksTest extends AbstractTest
|
||||
{
|
||||
private static $symlinkOnWindows = null;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
|
||||
self::$symlinkOnWindows = true;
|
||||
$originDir = tempnam(sys_get_temp_dir(), 'sl');
|
||||
$targetDir = tempnam(sys_get_temp_dir(), 'sl');
|
||||
if (true !== @symlink($originDir, $targetDir)) {
|
||||
$report = error_get_last();
|
||||
if (is_array($report) && false !== strpos($report['message'], 'error code(1314)')) {
|
||||
self::$symlinkOnWindows = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function hookPath($repository, $hook)
|
||||
{
|
||||
return $repository->getGitDir().'/hooks/'.$hook;
|
||||
}
|
||||
|
||||
public function touchHook($repository, $hook, $content = '')
|
||||
{
|
||||
$path = $this->hookPath($repository, $hook);
|
||||
file_put_contents($path, $content);
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
public function assertHasHook($repository, $hook)
|
||||
{
|
||||
$file = $this->hookPath($repository, $hook);
|
||||
|
||||
$this->assertTrue($repository->getHooks()->has($hook), "hook $hook in repository");
|
||||
$this->assertTrue(file_exists($file), "Hook $hook is present");
|
||||
}
|
||||
|
||||
public function assertNoHook($repository, $hook)
|
||||
{
|
||||
$file = $this->hookPath($repository, $hook);
|
||||
|
||||
$this->assertFalse($repository->getHooks()->has($hook), "No hook $hook in repository");
|
||||
$this->assertFalse(file_exists($file), "Hook $hook is not present");
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testHas($repository)
|
||||
{
|
||||
$this->assertNoHook($repository, 'foo');
|
||||
$this->touchHook($repository, 'foo');
|
||||
$this->assertHasHook($repository, 'foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
* @expectedException InvalidArgumentException
|
||||
*/
|
||||
public function testGet_InvalidName_ThrowsException($repository)
|
||||
{
|
||||
$repository->getHooks()->get('foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGet($repository)
|
||||
{
|
||||
$this->touchHook($repository, 'foo', 'foobar');
|
||||
|
||||
$this->assertEquals('foobar', $repository->getHooks()->get('foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testSymlink($repository)
|
||||
{
|
||||
$this->markAsSkippedIfSymlinkIsMissing();
|
||||
|
||||
$file = $this->touchHook($repository, 'bar', 'barbarbar');
|
||||
$repository->getHooks()->setSymlink('foo', $file);
|
||||
|
||||
$this->assertTrue(is_link($this->hookPath($repository, 'foo')), 'foo hook is a symlink');
|
||||
$this->assertEquals($file, readlink($this->hookPath($repository, 'foo')), 'target of symlink is correct');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
* @expectedException LogicException
|
||||
*/
|
||||
public function testSymlink_WithExisting_ThrowsLogicException($repository)
|
||||
{
|
||||
$this->markAsSkippedIfSymlinkIsMissing();
|
||||
|
||||
$file = $this->hookPath($repository, 'target-symlink');
|
||||
$fooFile = $this->hookPath($repository, 'foo');
|
||||
|
||||
file_put_contents($file, 'foobar');
|
||||
touch($fooFile);
|
||||
|
||||
$repository->getHooks()->setSymlink('foo', $file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testSet($repository)
|
||||
{
|
||||
$file = $this->hookPath($repository, 'foo');
|
||||
$repository->getHooks()->set('foo', 'bar');
|
||||
|
||||
$this->assertEquals('bar', file_get_contents($file), 'Hook content is correct');
|
||||
|
||||
$perms = fileperms($file);
|
||||
$this->assertEquals(defined('PHP_WINDOWS_VERSION_BUILD') ? 0666 : 0777, $perms & 0777, 'Hook permissions are correct');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testSet_Existing_ThrowsLogicException($repository)
|
||||
{
|
||||
$repository->getHooks()->set('foo', 'bar');
|
||||
|
||||
$this->setExpectedException('LogicException');
|
||||
$repository->getHooks()->set('foo', 'bar');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testRemove($repository)
|
||||
{
|
||||
$file = $this->hookPath($repository, 'foo');
|
||||
touch($file);
|
||||
|
||||
$repository->getHooks()->remove('foo');
|
||||
$this->assertFalse(file_exists($file));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
* @expectedException LogicException
|
||||
*/
|
||||
public function testRemove_NotExisting_ThrowsLogicException($repository)
|
||||
{
|
||||
$repository->getHooks()->remove('foo');
|
||||
}
|
||||
|
||||
private function markAsSkippedIfSymlinkIsMissing()
|
||||
{
|
||||
if (!function_exists('symlink')) {
|
||||
$this->markTestSkipped('symlink is not supported');
|
||||
}
|
||||
|
||||
if (defined('PHP_WINDOWS_VERSION_MAJOR') && false === self::$symlinkOnWindows) {
|
||||
$this->markTestSkipped('symlink requires "Create symbolic links" privilege on windows');
|
||||
}
|
||||
}
|
||||
}
|
80
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/LogTest.php
vendored
Normal file
80
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/LogTest.php
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Tests;
|
||||
|
||||
use Gitonomy\Git\Log;
|
||||
|
||||
class LogTest extends AbstractTest
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testRevisionAndPath($repository)
|
||||
{
|
||||
$logReadme = $repository->getLog(self::LONGFILE_COMMIT, 'README');
|
||||
$logImage = $repository->getLog(self::LONGFILE_COMMIT, 'image.jpg');
|
||||
|
||||
$this->assertEquals(3, count($logReadme));
|
||||
$this->assertEquals(2, count($logImage));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetCommits($repository)
|
||||
{
|
||||
$log = $repository->getLog(self::LONGFILE_COMMIT, null, null, 3);
|
||||
|
||||
$commits = $log->getCommits();
|
||||
|
||||
$this->assertEquals(3, count($commits), '3 commits in log');
|
||||
$this->assertEquals(self::LONGFILE_COMMIT, $commits[0]->getHash(), 'First is requested one');
|
||||
$this->assertEquals(self::BEFORE_LONGFILE_COMMIT, $commits[1]->getHash(), "Second is longfile parent\'s");
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testCountCommits($repository)
|
||||
{
|
||||
$log = $repository->getLog(self::LONGFILE_COMMIT, null, 2, 3);
|
||||
|
||||
$this->assertEquals(8, $log->countCommits(), '8 commits found in history');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testCountAllCommits($repository)
|
||||
{
|
||||
$log = $log = $repository->getLog();
|
||||
|
||||
$this->assertGreaterThan(100, $log->countCommits(), 'Returns all commits from all branches');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testIterable($repository)
|
||||
{
|
||||
$log = $repository->getLog(self::LONGFILE_COMMIT);
|
||||
|
||||
$expectedHashes = array(self::LONGFILE_COMMIT, self::BEFORE_LONGFILE_COMMIT);
|
||||
foreach ($log as $entry) {
|
||||
$hash = array_shift($expectedHashes);
|
||||
$this->assertEquals($hash, $entry->getHash());
|
||||
if (count($expectedHashes) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
82
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/PushReferenceTest.php
vendored
Normal file
82
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/PushReferenceTest.php
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Tests;
|
||||
|
||||
use Gitonomy\Git\PushReference;
|
||||
|
||||
class PushReferenceTest extends AbstractTest
|
||||
{
|
||||
const CREATE = 1;
|
||||
const DELETE = 2;
|
||||
const FORCE = 4;
|
||||
const FAST_FORWARD = 8;
|
||||
|
||||
public function provideIsers()
|
||||
{
|
||||
// mask: force fastforward create delete
|
||||
return array(
|
||||
array('foo', PushReference::ZERO, self::LONGFILE_COMMIT, self::CREATE),
|
||||
array('foo', self::LONGFILE_COMMIT, PushReference::ZERO, self::DELETE),
|
||||
array('foo', self::LONGFILE_COMMIT, self::BEFORE_LONGFILE_COMMIT, self::FORCE),
|
||||
array('foo', self::BEFORE_LONGFILE_COMMIT, self::LONGFILE_COMMIT, self::FAST_FORWARD),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideIsers
|
||||
*/
|
||||
public function testIsers($reference, $before, $after, $mask)
|
||||
{
|
||||
$reference = new PushReference(self::createFoobarRepository(), $reference, $before, $after);
|
||||
$this->assertEquals($mask & self::CREATE, $reference->isCreate(), 'Create value is correct.');
|
||||
$this->assertEquals($mask & self::DELETE, $reference->isDelete(), 'Delete value is correct.');
|
||||
$this->assertEquals($mask & self::FORCE, $reference->isForce(), 'Force value is correct.');
|
||||
$this->assertEquals($mask & self::FAST_FORWARD, $reference->isFastForward(), 'FastForward value is correct.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testLog($repository)
|
||||
{
|
||||
$ref = new PushReference($repository, 'foo', self::INITIAL_COMMIT, self::LONGFILE_COMMIT);
|
||||
|
||||
$log = $ref->getLog()->getCommits();
|
||||
$this->assertEquals(7, count($log), '7 commits in log');
|
||||
$this->assertEquals('add a long file', $log[0]->getShortMessage(), 'First commit is correct');
|
||||
}
|
||||
|
||||
/**
|
||||
* This test ensures that GPG signed requests does not break the reading of commit logs.
|
||||
*
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testSignedLog($repository)
|
||||
{
|
||||
$ref = new PushReference($repository, 'foo', self::INITIAL_COMMIT, self::SIGNED_COMMIT);
|
||||
$log = $ref->getLog()->getCommits();
|
||||
$this->assertEquals(16, count($log), '16 commits in log');
|
||||
$this->assertEquals('signed commit', $log[0]->getShortMessage(), 'Last commit is correct');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testLogWithExclude($repository)
|
||||
{
|
||||
$ref = new PushReference($repository, 'foo', PushReference::ZERO, self::LONGFILE_COMMIT);
|
||||
|
||||
$log = $ref->getLog(array(self::INITIAL_COMMIT))->getCommits();
|
||||
$this->assertEquals(7, count($log), '7 commits in log');
|
||||
$this->assertEquals('add a long file', $log[0]->getShortMessage(), 'First commit is correct');
|
||||
}
|
||||
}
|
183
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/ReferenceTest.php
vendored
Normal file
183
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/ReferenceTest.php
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Tests;
|
||||
|
||||
use Gitonomy\Git\Reference\Branch;
|
||||
use Gitonomy\Git\Reference\Tag;
|
||||
|
||||
class ReferenceTest extends AbstractTest
|
||||
{
|
||||
private $references;
|
||||
|
||||
/**
|
||||
* @dataProvider provideEmpty
|
||||
*/
|
||||
public function testEmptyRepository($repository)
|
||||
{
|
||||
$this->assertCount(0, $repository->getReferences());
|
||||
$this->assertEquals(array(), $repository->getReferences()->getAll());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetBranch($repository)
|
||||
{
|
||||
$branch = $repository->getReferences()->getBranch('master');
|
||||
|
||||
$this->assertTrue($branch instanceof Branch, 'Branch object is correct type');
|
||||
$this->assertEquals($branch->getCommitHash(), $branch->getCommit()->getHash(), 'Hash is correctly resolved');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testHasBranch($repository)
|
||||
{
|
||||
$this->assertTrue($repository->getReferences()->hasBranch('master'), 'Branch master exists');
|
||||
$this->assertFalse($repository->getReferences()->hasBranch('foobar'), 'Branch foobar does not exists');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testHasTag($repository)
|
||||
{
|
||||
$this->assertTrue($repository->getReferences()->hasTag('0.1'), 'Tag 0.1 exists');
|
||||
$this->assertFalse($repository->getReferences()->hasTag('foobar'), 'Tag foobar does not exists');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
* @expectedException Gitonomy\Git\Exception\ReferenceNotFoundException
|
||||
*/
|
||||
public function testGetBranch_NotExisting_Error($repository)
|
||||
{
|
||||
$branch = $repository->getReferences()->getBranch('notexisting');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetTag($repository)
|
||||
{
|
||||
$tag = $repository->getReferences()->getTag('0.1');
|
||||
|
||||
$this->assertTrue($tag instanceof Tag, 'Tag object is correct type');
|
||||
|
||||
$this->assertEquals(self::LONGFILE_COMMIT, $tag->getCommitHash(), 'Commit hash is correct');
|
||||
$this->assertEquals(self::LONGFILE_COMMIT, $tag->getCommit()->getHash(), 'Commit hash is correct');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
* @expectedException Gitonomy\Git\Exception\ReferenceNotFoundException
|
||||
*/
|
||||
public function testGetTag_NotExisting_Error($repository)
|
||||
{
|
||||
$branch = $repository->getReferences()->getTag('notexisting');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testResolve($repository)
|
||||
{
|
||||
$commit = $repository->getReferences()->getTag('0.1')->getCommit();
|
||||
$resolved = $repository->getReferences()->resolve($commit->getHash());
|
||||
|
||||
$this->assertEquals(1, count($resolved), '1 revision resolved');
|
||||
$this->assertTrue(reset($resolved) instanceof Tag, 'Resolved object is a tag');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testResolveTags($repository)
|
||||
{
|
||||
$commit = $repository->getReferences()->getTag('0.1')->getCommit();
|
||||
$resolved = $repository->getReferences()->resolveTags($commit->getHash());
|
||||
|
||||
$this->assertEquals(1, count($resolved), '1 revision resolved');
|
||||
$this->assertTrue(reset($resolved) instanceof Tag, 'Resolved object is a tag');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testResolveBranches($repository)
|
||||
{
|
||||
$master = $repository->getReferences()->getBranch('master');
|
||||
|
||||
$resolved = $repository->getReferences()->resolveBranches($master->getCommitHash());
|
||||
|
||||
if ($repository->isBare()) {
|
||||
$this->assertEquals(1, count($resolved), '1 revision resolved');
|
||||
} else {
|
||||
$this->assertEquals(2, count($resolved), '2 revision resolved');
|
||||
}
|
||||
|
||||
$this->assertTrue(reset($resolved) instanceof Branch, 'Resolved object is a branch');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testCountable($repository)
|
||||
{
|
||||
$this->assertGreaterThanOrEqual(2, count($repository->getReferences()), 'At least two references in repository');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testIterable($repository)
|
||||
{
|
||||
$i = 0;
|
||||
foreach ($repository->getReferences() as $ref) {
|
||||
++$i;
|
||||
}
|
||||
$this->assertGreaterThanOrEqual(2, $i, 'At least two references in repository');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testCreateAndDeleteTag($repository)
|
||||
{
|
||||
$references = $repository->getReferences();
|
||||
$tag = $references->createTag('0.0', self::INITIAL_COMMIT);
|
||||
|
||||
$this->assertTrue($references->hasTag('0.0'), 'Tag 0.0 created');
|
||||
$this->assertEquals(self::INITIAL_COMMIT, $tag->getCommit()->getHash());
|
||||
$this->assertSame($tag, $references->getTag('0.0'));
|
||||
|
||||
$tag->delete();
|
||||
$this->assertFalse($references->hasTag('0.0'), 'Tag 0.0 removed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testCreateAndDeleteBranch($repository)
|
||||
{
|
||||
$references = $repository->getReferences();
|
||||
$branch = $references->createBranch('foobar', self::INITIAL_COMMIT);
|
||||
|
||||
$this->assertTrue($references->hasBranch('foobar'), 'Branch foobar created');
|
||||
$this->assertEquals(self::INITIAL_COMMIT, $branch->getCommit()->getHash());
|
||||
$this->assertSame($branch, $references->getBranch('foobar'));
|
||||
|
||||
$branch->delete();
|
||||
$this->assertFalse($references->hasBranch('foobar'), 'Branch foobar removed');
|
||||
}
|
||||
}
|
109
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/RepositoryTest.php
vendored
Normal file
109
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/RepositoryTest.php
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Tests;
|
||||
|
||||
use Gitonomy\Git\Blob;
|
||||
use Gitonomy\Git\Repository;
|
||||
use Prophecy\Argument;
|
||||
|
||||
class RepositoryTest extends AbstractTest
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetBlob_WithExisting_Works($repository)
|
||||
{
|
||||
$blob = $repository->getCommit(self::LONGFILE_COMMIT)->getTree()->resolvePath('README.md');
|
||||
|
||||
$this->assertTrue($blob instanceof Blob, 'getBlob() returns a Blob object');
|
||||
$this->assertContains('Foo Bar project', $blob->getContent(), 'file is correct');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetSize($repository)
|
||||
{
|
||||
$size = $repository->getSize();
|
||||
$this->assertGreaterThan(70, $size, 'Repository is greater than 70KB');
|
||||
}
|
||||
|
||||
public function testIsBare()
|
||||
{
|
||||
$bare = self::createFoobarRepository(true);
|
||||
$this->assertTrue($bare->isBare(), 'Lib repository is bare');
|
||||
|
||||
$notBare = self::createFoobarRepository(false);
|
||||
$this->assertFalse($notBare->isBare(), 'Working copy is not bare');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetDescription($repository)
|
||||
{
|
||||
$this->assertSame("Unnamed repository; edit this file 'description' to name the repository.\n", $repository->getDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testLoggerOk($repository)
|
||||
{
|
||||
if (!interface_exists('Psr\Log\LoggerInterface')) {
|
||||
$this->markTestSkipped();
|
||||
}
|
||||
|
||||
$loggerProphecy = $this->prophesize('Psr\Log\LoggerInterface');
|
||||
$loggerProphecy
|
||||
->info('run command: remote "" ')
|
||||
->shouldBeCalledTimes(1)
|
||||
;
|
||||
$loggerProphecy
|
||||
->debug(Argument::type('string')) // duration, return code and output
|
||||
->shouldBeCalledTimes(3)
|
||||
;
|
||||
|
||||
$repository->setLogger($loggerProphecy->reveal());
|
||||
|
||||
$repository->run('remote');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
* @expectedException RuntimeException
|
||||
*/
|
||||
public function testLoggerNOk($repository)
|
||||
{
|
||||
if (!interface_exists('Psr\Log\LoggerInterface')) {
|
||||
$this->markTestSkipped();
|
||||
}
|
||||
|
||||
$loggerProphecy = $this->prophesize('Psr\Log\LoggerInterface');
|
||||
$loggerProphecy
|
||||
->info(Argument::type('string'))
|
||||
->shouldBeCalledTimes(1)
|
||||
;
|
||||
$loggerProphecy
|
||||
->debug(Argument::type('string')) // duration, return code and output
|
||||
->shouldBeCalledTimes(3)
|
||||
;
|
||||
$loggerProphecy
|
||||
->error(Argument::type('string'))
|
||||
->shouldBeCalledTimes(1)
|
||||
;
|
||||
|
||||
$repository->setLogger($loggerProphecy->reveal());
|
||||
|
||||
$repository->run('not-work');
|
||||
}
|
||||
}
|
60
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/RevisionTest.php
vendored
Normal file
60
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/RevisionTest.php
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Tests;
|
||||
|
||||
use Gitonomy\Git\Commit;
|
||||
use Gitonomy\Git\Log;
|
||||
use Gitonomy\Git\Revision;
|
||||
|
||||
class RevisionTest extends AbstractTest
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetCommit($repository)
|
||||
{
|
||||
$revision = $repository->getRevision(self::LONGFILE_COMMIT.'^');
|
||||
|
||||
$this->assertTrue($revision instanceof Revision, 'Revision object type');
|
||||
|
||||
$commit = $revision->getCommit();
|
||||
|
||||
$this->assertTrue($commit instanceof Commit, 'getCommit returns a Commit');
|
||||
|
||||
$this->assertEquals(self::BEFORE_LONGFILE_COMMIT, $commit->getHash(), 'Resolution is correct');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
* @expectedException Gitonomy\Git\Exception\ReferenceNotFoundException
|
||||
* @expectedExceptionMessage Can not find revision "non-existent-commit"
|
||||
*/
|
||||
public function testGetFailingReference($repository)
|
||||
{
|
||||
$revision = $repository->getRevision('non-existent-commit')->getCommit();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoobar
|
||||
*/
|
||||
public function testGetLog($repository)
|
||||
{
|
||||
$revision = $repository->getRevision(self::LONGFILE_COMMIT);
|
||||
|
||||
$log = $revision->getLog(null, 2, 3);
|
||||
|
||||
$this->assertTrue($log instanceof Log, 'Log type object');
|
||||
$this->assertEquals(2, $log->getOffset(), 'Log offset is passed');
|
||||
$this->assertEquals(3, $log->getLimit(), 'Log limit is passed');
|
||||
$this->assertEquals(array($revision), $log->getRevisions()->getAll(), 'Revision is passed');
|
||||
}
|
||||
}
|
48
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/TreeTest.php
vendored
Normal file
48
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/TreeTest.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Tests;
|
||||
|
||||
use Gitonomy\Git\Blob;
|
||||
|
||||
class TreeTest extends AbstractTest
|
||||
{
|
||||
const PATH_RESOLVING_COMMIT = 'cc06ac171d884282202dff88c1ded499a1f89420';
|
||||
/**
|
||||
* @dataProvider provideFooBar
|
||||
*/
|
||||
public function testCase($repository)
|
||||
{
|
||||
$tree = $repository->getCommit(self::LONGFILE_COMMIT)->getTree();
|
||||
|
||||
$entries = $tree->getEntries();
|
||||
|
||||
$this->assertTrue(isset($entries['long.php']), 'long.php is present');
|
||||
$this->assertTrue($entries['long.php'][1] instanceof Blob, 'long.php is a Blob');
|
||||
|
||||
$this->assertTrue(isset($entries['README.md']), 'README.md is present');
|
||||
$this->assertTrue($entries['README.md'][1] instanceof Blob, 'README.md is a Blob');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFooBar
|
||||
*/
|
||||
public function testResolvePath($repository)
|
||||
{
|
||||
$tree = $repository->getCommit(self::PATH_RESOLVING_COMMIT)->getTree();
|
||||
$path = 'test/a/b/c';
|
||||
|
||||
$resolved = $tree->resolvePath($path);
|
||||
$entries = $resolved->getEntries();
|
||||
|
||||
$this->assertTrue(isset($entries['d']), 'Successfully resolved source folder');
|
||||
}
|
||||
}
|
112
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/WorkingCopyTest.php
vendored
Normal file
112
vendor/gitonomy/gitlib/tests/Gitonomy/Git/Tests/WorkingCopyTest.php
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of Gitonomy.
|
||||
*
|
||||
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
namespace Gitonomy\Git\Tests;
|
||||
|
||||
use Gitonomy\Git\Admin;
|
||||
use Gitonomy\Git\Reference\Branch;
|
||||
|
||||
class WorkingCopyTest extends AbstractTest
|
||||
{
|
||||
/**
|
||||
* @expectedException LogicException
|
||||
*/
|
||||
public function testNoWorkingCopyInBare()
|
||||
{
|
||||
$path = self::createTempDir();
|
||||
$repo = Admin::init($path, true, self::getOptions());
|
||||
|
||||
$repo->getWorkingCopy();
|
||||
}
|
||||
|
||||
public function testCheckout()
|
||||
{
|
||||
$repository = self::createFoobarRepository(false);
|
||||
$wc = $repository->getWorkingCopy();
|
||||
$wc->checkout('origin/new-feature', 'new-feature');
|
||||
|
||||
$head = $repository->getHead();
|
||||
$this->assertTrue($head instanceof Branch, 'HEAD is a branch');
|
||||
$this->assertEquals('new-feature', $head->getName(), 'HEAD is branch new-feature');
|
||||
}
|
||||
|
||||
public function testDiffStaged()
|
||||
{
|
||||
$repository = self::createFoobarRepository(false);
|
||||
$wc = $repository->getWorkingCopy();
|
||||
|
||||
$diffStaged = $wc->getDiffStaged();
|
||||
$this->assertCount(0, $diffStaged->getFiles());
|
||||
|
||||
$file = $repository->getWorkingDir().'/foobar-test';
|
||||
file_put_contents($file, 'test');
|
||||
$repository->run('add', array($file));
|
||||
|
||||
$diffStaged = $wc->getDiffStaged();
|
||||
$this->assertCount(1, $diffStaged->getFiles());
|
||||
}
|
||||
|
||||
public function testDiffPending()
|
||||
{
|
||||
$repository = self::createFoobarRepository(false);
|
||||
$wc = $repository->getWorkingCopy();
|
||||
|
||||
$diffPending = $wc->getDiffPending();
|
||||
$this->assertCount(0, $diffPending->getFiles());
|
||||
|
||||
$file = $repository->getWorkingDir().'/test.sh';
|
||||
file_put_contents($file, 'test');
|
||||
|
||||
$diffPending = $wc->getDiffPending();
|
||||
$this->assertCount(1, $diffPending->getFiles());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException RuntimeException
|
||||
*/
|
||||
public function testCheckoutUnexisting()
|
||||
{
|
||||
self::createFoobarRepository(false)->getWorkingCopy()->checkout('foobar');
|
||||
}
|
||||
|
||||
public function testAttachedHead()
|
||||
{
|
||||
$repository = self::createFoobarRepository(false);
|
||||
$wc = $repository->getWorkingCopy();
|
||||
$wc->checkout('master');
|
||||
|
||||
$head = $repository->getHead();
|
||||
$this->assertTrue($repository->isHeadAttached(), 'HEAD is attached');
|
||||
$this->assertFalse($repository->isHeadDetached(), 'HEAD is not detached');
|
||||
}
|
||||
|
||||
public function testDetachedHead()
|
||||
{
|
||||
$repository = self::createFoobarRepository(false);
|
||||
$wc = $repository->getWorkingCopy();
|
||||
$wc->checkout('0.1');
|
||||
|
||||
$head = $repository->getHead();
|
||||
$this->assertFalse($repository->isHeadAttached(), 'HEAD is not attached');
|
||||
$this->assertTrue($repository->isHeadDetached(), 'HEAD is detached');
|
||||
}
|
||||
|
||||
public function testGetUntracked()
|
||||
{
|
||||
$repository = self::createFoobarRepository(false);
|
||||
$wc = $repository->getWorkingCopy();
|
||||
|
||||
$file = $repository->getWorkingDir().'/untracked.txt';
|
||||
file_put_contents($file, 'foo');
|
||||
|
||||
$this->assertContains('untracked.txt', $wc->getUntrackedFiles());
|
||||
}
|
||||
}
|
14
vendor/gitonomy/gitlib/tests/bootstrap.php
vendored
Normal file
14
vendor/gitonomy/gitlib/tests/bootstrap.php
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
require __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
|
||||
$server = array_change_key_case($_SERVER, true);
|
||||
$_SERVER['GIT_ENVS'] = array();
|
||||
foreach (array('PATH', 'SYSTEMROOT') as $key) {
|
||||
if (isset($server[$key])) {
|
||||
$_SERVER['GIT_ENVS'][$key] = $server[$key];
|
||||
}
|
||||
}
|
||||
unset($server);
|
||||
}
|
Reference in New Issue
Block a user