/trunk/vendor/danielmarschall/glip/Git forks.txt |
---|
0,0 → 1,34 |
As of April 2023, the following forks have commits ahead of the original patrikf/glip: |
AlexFBP / glip |
alexgorbatchev / glip |
antmicro / glip |
laurentj / glip |
mitgedanken-lab / php-glip |
Ap0ught-Old / glip |
aredridel / Glip |
captn3m0 / glip |
Ennosuke / glip |
guiwoda / glip |
halstead / glip |
jkufner / glip |
kokareff / glip |
locked / glip |
markopavlovic / glip |
mgirouard / glip |
MiltoxBeyond / glip |
rafaelgieschke / glip |
redotheoffice / glip |
h0tw1r3 / glip |
xaav / glip |
sarkian / glip |
yamek / glip |
shetland / glip |
signalizatoredu / glip |
Upliner / glip |
xero / glip |
yendor / glip |
We need to check if there are things which we could use, too. |
/trunk/vendor/danielmarschall/glip/LICENSE |
---|
0,0 → 1,339 |
GNU GENERAL PUBLIC LICENSE |
Version 2, June 1991 |
Copyright (C) 1989, 1991 Free Software Foundation, Inc., |
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
Everyone is permitted to copy and distribute verbatim copies |
of this license document, but changing it is not allowed. |
Preamble |
The licenses for most software are designed to take away your |
freedom to share and change it. By contrast, the GNU General Public |
License is intended to guarantee your freedom to share and change free |
software--to make sure the software is free for all its users. This |
General Public License applies to most of the Free Software |
Foundation's software and to any other program whose authors commit to |
using it. (Some other Free Software Foundation software is covered by |
the GNU Lesser General Public License instead.) You can apply it to |
your programs, too. |
When we speak of free software, we are referring to freedom, not |
price. Our General Public Licenses are designed to make sure that you |
have the freedom to distribute copies of free software (and charge for |
this service if you wish), that you receive source code or can get it |
if you want it, that you can change the software or use pieces of it |
in new free programs; and that you know you can do these things. |
To protect your rights, we need to make restrictions that forbid |
anyone to deny you these rights or to ask you to surrender the rights. |
These restrictions translate to certain responsibilities for you if you |
distribute copies of the software, or if you modify it. |
For example, if you distribute copies of such a program, whether |
gratis or for a fee, you must give the recipients all the rights that |
you have. You must make sure that they, too, receive or can get the |
source code. And you must show them these terms so they know their |
rights. |
We protect your rights with two steps: (1) copyright the software, and |
(2) offer you this license which gives you legal permission to copy, |
distribute and/or modify the software. |
Also, for each author's protection and ours, we want to make certain |
that everyone understands that there is no warranty for this free |
software. If the software is modified by someone else and passed on, we |
want its recipients to know that what they have is not the original, so |
that any problems introduced by others will not reflect on the original |
authors' reputations. |
Finally, any free program is threatened constantly by software |
patents. We wish to avoid the danger that redistributors of a free |
program will individually obtain patent licenses, in effect making the |
program proprietary. To prevent this, we have made it clear that any |
patent must be licensed for everyone's free use or not licensed at all. |
The precise terms and conditions for copying, distribution and |
modification follow. |
GNU GENERAL PUBLIC LICENSE |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
0. This License applies to any program or other work which contains |
a notice placed by the copyright holder saying it may be distributed |
under the terms of this General Public License. The "Program", below, |
refers to any such program or work, and a "work based on the Program" |
means either the Program or any derivative work under copyright law: |
that is to say, a work containing the Program or a portion of it, |
either verbatim or with modifications and/or translated into another |
language. (Hereinafter, translation is included without limitation in |
the term "modification".) Each licensee is addressed as "you". |
Activities other than copying, distribution and modification are not |
covered by this License; they are outside its scope. The act of |
running the Program is not restricted, and the output from the Program |
is covered only if its contents constitute a work based on the |
Program (independent of having been made by running the Program). |
Whether that is true depends on what the Program does. |
1. You may copy and distribute verbatim copies of the Program's |
source code as you receive it, in any medium, provided that you |
conspicuously and appropriately publish on each copy an appropriate |
copyright notice and disclaimer of warranty; keep intact all the |
notices that refer to this License and to the absence of any warranty; |
and give any other recipients of the Program a copy of this License |
along with the Program. |
You may charge a fee for the physical act of transferring a copy, and |
you may at your option offer warranty protection in exchange for a fee. |
2. You may modify your copy or copies of the Program or any portion |
of it, thus forming a work based on the Program, and copy and |
distribute such modifications or work under the terms of Section 1 |
above, provided that you also meet all of these conditions: |
a) You must cause the modified files to carry prominent notices |
stating that you changed the files and the date of any change. |
b) You must cause any work that you distribute or publish, that in |
whole or in part contains or is derived from the Program or any |
part thereof, to be licensed as a whole at no charge to all third |
parties under the terms of this License. |
c) If the modified program normally reads commands interactively |
when run, you must cause it, when started running for such |
interactive use in the most ordinary way, to print or display an |
announcement including an appropriate copyright notice and a |
notice that there is no warranty (or else, saying that you provide |
a warranty) and that users may redistribute the program under |
these conditions, and telling the user how to view a copy of this |
License. (Exception: if the Program itself is interactive but |
does not normally print such an announcement, your work based on |
the Program is not required to print an announcement.) |
These requirements apply to the modified work as a whole. If |
identifiable sections of that work are not derived from the Program, |
and can be reasonably considered independent and separate works in |
themselves, then this License, and its terms, do not apply to those |
sections when you distribute them as separate works. But when you |
distribute the same sections as part of a whole which is a work based |
on the Program, the distribution of the whole must be on the terms of |
this License, whose permissions for other licensees extend to the |
entire whole, and thus to each and every part regardless of who wrote it. |
Thus, it is not the intent of this section to claim rights or contest |
your rights to work written entirely by you; rather, the intent is to |
exercise the right to control the distribution of derivative or |
collective works based on the Program. |
In addition, mere aggregation of another work not based on the Program |
with the Program (or with a work based on the Program) on a volume of |
a storage or distribution medium does not bring the other work under |
the scope of this License. |
3. You may copy and distribute the Program (or a work based on it, |
under Section 2) in object code or executable form under the terms of |
Sections 1 and 2 above provided that you also do one of the following: |
a) Accompany it with the complete corresponding machine-readable |
source code, which must be distributed under the terms of Sections |
1 and 2 above on a medium customarily used for software interchange; or, |
b) Accompany it with a written offer, valid for at least three |
years, to give any third party, for a charge no more than your |
cost of physically performing source distribution, a complete |
machine-readable copy of the corresponding source code, to be |
distributed under the terms of Sections 1 and 2 above on a medium |
customarily used for software interchange; or, |
c) Accompany it with the information you received as to the offer |
to distribute corresponding source code. (This alternative is |
allowed only for noncommercial distribution and only if you |
received the program in object code or executable form with such |
an offer, in accord with Subsection b above.) |
The source code for a work means the preferred form of the work for |
making modifications to it. For an executable work, complete source |
code means all the source code for all modules it contains, plus any |
associated interface definition files, plus the scripts used to |
control compilation and installation of the executable. However, as a |
special exception, the source code distributed need not include |
anything that is normally distributed (in either source or binary |
form) with the major components (compiler, kernel, and so on) of the |
operating system on which the executable runs, unless that component |
itself accompanies the executable. |
If distribution of executable or object code is made by offering |
access to copy from a designated place, then offering equivalent |
access to copy the source code from the same place counts as |
distribution of the source code, even though third parties are not |
compelled to copy the source along with the object code. |
4. You may not copy, modify, sublicense, or distribute the Program |
except as expressly provided under this License. Any attempt |
otherwise to copy, modify, sublicense or distribute the Program is |
void, and will automatically terminate your rights under this License. |
However, parties who have received copies, or rights, from you under |
this License will not have their licenses terminated so long as such |
parties remain in full compliance. |
5. You are not required to accept this License, since you have not |
signed it. However, nothing else grants you permission to modify or |
distribute the Program or its derivative works. These actions are |
prohibited by law if you do not accept this License. Therefore, by |
modifying or distributing the Program (or any work based on the |
Program), you indicate your acceptance of this License to do so, and |
all its terms and conditions for copying, distributing or modifying |
the Program or works based on it. |
6. Each time you redistribute the Program (or any work based on the |
Program), the recipient automatically receives a license from the |
original licensor to copy, distribute or modify the Program subject to |
these terms and conditions. You may not impose any further |
restrictions on the recipients' exercise of the rights granted herein. |
You are not responsible for enforcing compliance by third parties to |
this License. |
7. If, as a consequence of a court judgment or allegation of patent |
infringement or for any other reason (not limited to patent issues), |
conditions are imposed on you (whether by court order, agreement or |
otherwise) that contradict the conditions of this License, they do not |
excuse you from the conditions of this License. If you cannot |
distribute so as to satisfy simultaneously your obligations under this |
License and any other pertinent obligations, then as a consequence you |
may not distribute the Program at all. For example, if a patent |
license would not permit royalty-free redistribution of the Program by |
all those who receive copies directly or indirectly through you, then |
the only way you could satisfy both it and this License would be to |
refrain entirely from distribution of the Program. |
If any portion of this section is held invalid or unenforceable under |
any particular circumstance, the balance of the section is intended to |
apply and the section as a whole is intended to apply in other |
circumstances. |
It is not the purpose of this section to induce you to infringe any |
patents or other property right claims or to contest validity of any |
such claims; this section has the sole purpose of protecting the |
integrity of the free software distribution system, which is |
implemented by public license practices. Many people have made |
generous contributions to the wide range of software distributed |
through that system in reliance on consistent application of that |
system; it is up to the author/donor to decide if he or she is willing |
to distribute software through any other system and a licensee cannot |
impose that choice. |
This section is intended to make thoroughly clear what is believed to |
be a consequence of the rest of this License. |
8. If the distribution and/or use of the Program is restricted in |
certain countries either by patents or by copyrighted interfaces, the |
original copyright holder who places the Program under this License |
may add an explicit geographical distribution limitation excluding |
those countries, so that distribution is permitted only in or among |
countries not thus excluded. In such case, this License incorporates |
the limitation as if written in the body of this License. |
9. The Free Software Foundation may publish revised and/or new versions |
of the General Public License from time to time. Such new versions will |
be similar in spirit to the present version, but may differ in detail to |
address new problems or concerns. |
Each version is given a distinguishing version number. If the Program |
specifies a version number of this License which applies to it and "any |
later version", you have the option of following the terms and conditions |
either of that version or of any later version published by the Free |
Software Foundation. If the Program does not specify a version number of |
this License, you may choose any version ever published by the Free Software |
Foundation. |
10. If you wish to incorporate parts of the Program into other free |
programs whose distribution conditions are different, write to the author |
to ask for permission. For software which is copyrighted by the Free |
Software Foundation, write to the Free Software Foundation; we sometimes |
make exceptions for this. Our decision will be guided by the two goals |
of preserving the free status of all derivatives of our free software and |
of promoting the sharing and reuse of software generally. |
NO WARRANTY |
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED |
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS |
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE |
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, |
REPAIR OR CORRECTION. |
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, |
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING |
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED |
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY |
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER |
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE |
POSSIBILITY OF SUCH DAMAGES. |
END OF TERMS AND CONDITIONS |
How to Apply These Terms to Your New Programs |
If you develop a new program, and you want it to be of the greatest |
possible use to the public, the best way to achieve this is to make it |
free software which everyone can redistribute and change under these terms. |
To do so, attach the following notices to the program. It is safest |
to attach them to the start of each source file to most effectively |
convey the exclusion of warranty; and each file should have at least |
the "copyright" line and a pointer to where the full notice is found. |
<one line to give the program's name and a brief idea of what it does.> |
Copyright (C) <year> <name of author> |
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation; either version 2 of the License, or |
(at your option) any later version. |
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
You should have received a copy of the GNU General Public License along |
with this program; if not, write to the Free Software Foundation, Inc., |
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
Also add information on how to contact you by electronic and paper mail. |
If the program is interactive, make it output a short notice like this |
when it starts in an interactive mode: |
Gnomovision version 69, Copyright (C) year name of author |
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
This is free software, and you are welcome to redistribute it |
under certain conditions; type `show c' for details. |
The hypothetical commands `show w' and `show c' should show the appropriate |
parts of the General Public License. Of course, the commands you use may |
be called something other than `show w' and `show c'; they could even be |
mouse-clicks or menu items--whatever suits your program. |
You should also get your employer (if you work as a programmer) or your |
school, if any, to sign a "copyright disclaimer" for the program, if |
necessary. Here is a sample; alter the names: |
Yoyodyne, Inc., hereby disclaims all copyright interest in the program |
`Gnomovision' (which makes passes at compilers) written by James Hacker. |
<signature of Ty Coon>, 1 April 1989 |
Ty Coon, President of Vice |
This General Public License does not permit incorporating your program into |
proprietary programs. If your program is a subroutine library, you may |
consider it more useful to permit linking proprietary applications with the |
library. If this is what you want to do, use the GNU Lesser General |
Public License instead of this License. |
/trunk/vendor/danielmarschall/glip/README.md |
---|
0,0 → 1,33 |
# glip (Git Library In PHP) |
glip is a Git Library In PHP. It allows you to access bare git repositories |
from PHP scripts, even without having git installed. |
Initially written by [Patrik Fimml](http://fimml.at/glip), it was forked slightly updated by Daniel Marschall in 2023. |
## Changes in the fork ## |
- Added composer.json |
- Added README.md |
- Removed Doxygen |
- Made compatible with PHP 8 |
- Fixed assertion error in GitCommitStamp |
- Added namespace and renamed files to their classname |
- Misc fixes to make PHPstan tests pass |
## Usage ## |
Add dependency in composer using the command `git require danielmarschall/glip`. |
Include the autoload file, as shown below: |
```php |
<?php |
use ViaThinkSoft\Glip\Git; |
require_once '/path/to/vendor/autoload.php'; |
$repo = new Git('project/.git'); |
``` |
/trunk/vendor/danielmarschall/glip/composer.json |
---|
0,0 → 1,37 |
{ |
"name": "danielmarschall/glip", |
"version": "0.1.3", |
"type": "library", |
"description": "Git library for PHP", |
"keywords": ["git"], |
"homepage": "https://fimml.at/projects/glip", |
"license": "GPL-2.0-or-later", |
"authors": [ |
{ |
"name": "Patrik Fimml", |
"email": "patrik@fimml.at", |
"homepage": "https://fimml.at/", |
"role": "Developer" |
}, |
{ |
"name": "Daniel Marschall", |
"email": "info@daniel-marschall.de", |
"homepage": "https://www.daniel-marschall.de/", |
"role": "Developer" |
} |
], |
"require": { |
"php": ">=5.2", |
"ext-zlib": "*" |
}, |
"autoload": { |
"psr-4": { |
"ViaThinkSoft\\Glip\\": "src/" |
} |
}, |
"extra": { |
"branch-alias": { |
"dev-master": "0.1.3-dev" |
} |
} |
} |
/trunk/vendor/danielmarschall/glip/phpstan.neon.dist |
---|
0,0 → 1,10 |
parameters: |
level: 5 |
fileExtensions: |
- php |
paths: |
- . |
excludePaths: |
analyseAndScan: |
- .phpstan |
tmpDir: .phpstan |
/trunk/vendor/danielmarschall/glip/src/Binary.php |
---|
0,0 → 1,64 |
<?php |
/* |
* binary.class.php: |
* Utility functions for dealing with binary files/strings. |
* All functions assume network byte order (big-endian). |
* |
* Copyright (C) 2008, 2009 Patrik Fimml |
* Copyright (c) 2023 Daniel Marschall |
* |
* This file is part of glip. |
* |
* glip is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 2 of the License, or |
* (at your option) any later version. |
* glip is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with glip. If not, see <http://www.gnu.org/licenses/>. |
*/ |
namespace ViaThinkSoft\Glip; |
final class Binary |
{ |
static public function uint16($str, $pos = 0) { |
return ord($str[$pos + 0]) << 8 | ord($str[$pos + 1]); |
} |
static public function uint32($str, $pos = 0) { |
$a = unpack('Nx', substr($str, $pos, 4)); |
return $a['x']; |
} |
static public function nuint32($n, $str, $pos = 0) { |
$r = array(); |
for ($i = 0; $i < $n; $i++, $pos += 4) |
$r[] = Binary::uint32($str, $pos); |
return $r; |
} |
static public function fuint32($f) { |
return Binary::uint32(fread($f, 4)); |
} |
static public function nfuint32($n, $f) { |
return Binary::nuint32($n, fread($f, 4 * $n)); |
} |
static public function git_varint($str, &$pos = 0) { |
$r = 0; |
$c = 0x80; |
for ($i = 0; $c & 0x80; $i += 7) { |
$c = ord($str[$pos++]); |
$r |= (($c & 0x7F) << $i); |
} |
return $r; |
} |
} |
/trunk/vendor/danielmarschall/glip/src/Git.php |
---|
0,0 → 1,370 |
<?php |
/* |
* Copyright (C) 2008, 2009 Patrik Fimml |
* Copyright (c) 2023 Daniel Marschall |
* |
* This file is part of glip. |
* |
* glip is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 2 of the License, or |
* (at your option) any later version. |
* glip is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with glip. If not, see <http://www.gnu.org/licenses/>. |
*/ |
namespace ViaThinkSoft\Glip; |
class Git |
{ |
public $dir; |
private $packs; |
const OBJ_NONE = 0; |
const OBJ_COMMIT = 1; |
const OBJ_TREE = 2; |
const OBJ_BLOB = 3; |
const OBJ_TAG = 4; |
const OBJ_OFS_DELTA = 6; |
const OBJ_REF_DELTA = 7; |
static public function getTypeID($name) { |
if ($name == 'commit') |
return Git::OBJ_COMMIT; |
else if ($name == 'tree') |
return Git::OBJ_TREE; |
else if ($name == 'blob') |
return Git::OBJ_BLOB; |
else if ($name == 'tag') |
return Git::OBJ_TAG; |
throw new \Exception(sprintf('unknown type name: %s', $name)); |
} |
static public function getTypeName($type) { |
if ($type == Git::OBJ_COMMIT) |
return 'commit'; |
else if ($type == Git::OBJ_TREE) |
return 'tree'; |
else if ($type == Git::OBJ_BLOB) |
return 'blob'; |
else if ($type == Git::OBJ_TAG) |
return 'tag'; |
throw new \Exception(sprintf('no string representation of type %d', $type)); |
} |
public function __construct($dir) { |
$this->dir = realpath($dir); |
if ($this->dir === false || !@is_dir($this->dir)) |
throw new \Exception(sprintf('not a directory: %s', $dir)); |
$this->packs = array(); |
$dh = opendir(sprintf('%s/objects/pack', $this->dir)); |
if ($dh !== false) { |
while (($entry = readdir($dh)) !== false) |
if (preg_match('#^pack-([0-9a-fA-F]{40})\.idx$#', $entry, $m)) |
$this->packs[] = pack('H40', $m[1]); |
closedir($dh); |
} |
} |
/** |
* @brief Tries to find $object_name in the fanout table in $f at $offset. |
* |
* @returns array The range where the object can be located (first possible |
* location and past-the-end location) |
*/ |
protected function readFanout($f, $object_name, $offset) { |
if ($object_name[0] == "\x00") { |
$cur = 0; |
fseek($f, $offset); |
$after = Binary::fuint32($f); |
} else { |
fseek($f, $offset + (ord($object_name[0]) - 1) * 4); |
$cur = Binary::fuint32($f); |
$after = Binary::fuint32($f); |
} |
return array($cur, $after); |
} |
/** |
* @brief Try to find an object in a pack. |
* |
* @param $object_name (string) name of the object (binary SHA1) |
* @returns (array) an array consisting of the name of the pack (string) and |
* the byte offset inside it, or NULL if not found |
*/ |
protected function findPackedObject($object_name) { |
foreach ($this->packs as $pack_name) { |
$index = fopen(sprintf('%s/objects/pack/pack-%s.idx', $this->dir, bin2hex($pack_name)), 'rb'); |
flock($index, LOCK_SH); |
/* check version */ |
$magic = fread($index, 4); |
if ($magic != "\xFFtOc") { |
/* version 1 */ |
/* read corresponding fanout entry */ |
list($cur, $after) = $this->readFanout($index, $object_name, 0); |
$n = $after - $cur; |
if ($n == 0) |
continue; |
/* |
* TODO: do a binary search in [$offset, $offset+24*$n) |
*/ |
fseek($index, 4 * 256 + 24 * $cur); |
for ($i = 0; $i < $n; $i++) { |
$off = Binary::fuint32($index); |
$name = fread($index, 20); |
if ($name == $object_name) { |
/* we found the object */ |
fclose($index); |
return array($pack_name, $off); |
} |
} |
} else { |
/* version 2+ */ |
$version = Binary::fuint32($index); |
if ($version == 2) { |
list($cur, $after) = $this->readFanout($index, $object_name, 8); |
if ($cur == $after) |
continue; |
fseek($index, 8 + 4 * 255); |
$total_objects = Binary::fuint32($index); |
/* look up sha1 */ |
fseek($index, 8 + 4 * 256 + 20 * $cur); |
for ($i = $cur; $i < $after; $i++) { |
$name = fread($index, 20); |
if ($name == $object_name) |
break; |
} |
if ($i == $after) |
continue; |
fseek($index, 8 + 4 * 256 + 24 * $total_objects + 4 * $i); |
$off = Binary::fuint32($index); |
if ($off & 0x80000000) { |
/* packfile > 2 GB. Gee, you really want to handle this |
* much data with PHP? |
*/ |
throw new \Exception('64-bit packfiles offsets not implemented'); |
} |
fclose($index); |
return array($pack_name, $off); |
} else |
throw new \Exception('unsupported pack index format'); |
} |
fclose($index); |
} |
/* not found */ |
return null; |
} |
/** |
* @brief Apply the git delta $delta to the byte sequence $base. |
* |
* @param $delta (string) the delta to apply |
* @param $base (string) the sequence to patch |
* @returns (string) the patched byte sequence |
*/ |
protected function applyDelta($delta, $base) { |
$pos = 0; |
$base_size = Binary::git_varint($delta, $pos); |
$result_size = Binary::git_varint($delta, $pos); |
$r = ''; |
while ($pos < strlen($delta)) { |
$opcode = ord($delta[$pos++]); |
if ($opcode & 0x80) { |
/* copy a part of $base */ |
$off = 0; |
if ($opcode & 0x01) $off = ord($delta[$pos++]); |
if ($opcode & 0x02) $off |= ord($delta[$pos++]) << 8; |
if ($opcode & 0x04) $off |= ord($delta[$pos++]) << 16; |
if ($opcode & 0x08) $off |= ord($delta[$pos++]) << 24; |
$len = 0; |
if ($opcode & 0x10) $len = ord($delta[$pos++]); |
if ($opcode & 0x20) $len |= ord($delta[$pos++]) << 8; |
if ($opcode & 0x40) $len |= ord($delta[$pos++]) << 16; |
if ($len == 0) $len = 0x10000; |
$r .= substr($base, $off, $len); |
} else { |
/* take the next $opcode bytes as they are */ |
$r .= substr($delta, $pos, $opcode); |
$pos += $opcode; |
} |
} |
return $r; |
} |
/** |
* @brief Unpack an object from a pack. |
* |
* @param $pack (resource) open .pack file |
* @param $object_offset (integer) offset of the object in the pack |
* @returns (array) an array consisting of the object type (int) and the |
* binary representation of the object (string) |
*/ |
protected function unpackObject($pack, $object_offset) { |
fseek($pack, $object_offset); |
/* read object header */ |
$c = ord(fgetc($pack)); |
$type = ($c >> 4) & 0x07; |
$size = $c & 0x0F; |
for ($i = 4; $c & 0x80; $i += 7) { |
$c = ord(fgetc($pack)); |
$size |= (($c & 0x7F) << $i); |
} |
/* compare sha1_file.c:1608 unpack_entry */ |
if ($type == Git::OBJ_COMMIT || $type == Git::OBJ_TREE || $type == Git::OBJ_BLOB || $type == Git::OBJ_TAG) { |
/* |
* We don't know the actual size of the compressed |
* data, so we'll assume it's less than |
* $object_size+512. |
* |
* FIXME use PHP stream filter API as soon as it behaves |
* consistently |
*/ |
$data = gzuncompress(fread($pack, $size + 512), $size); |
} else if ($type == Git::OBJ_OFS_DELTA) { |
/* 20 = maximum varint length for offset */ |
$buf = fread($pack, $size + 512 + 20); |
/* |
* contrary to varints in other places, this one is big endian |
* (and 1 is added each turn) |
* see sha1_file.c (get_delta_base) |
*/ |
$pos = 0; |
$offset = -1; |
do { |
$offset++; |
$c = ord($buf[$pos++]); |
$offset = ($offset << 7) + ($c & 0x7F); |
} while ($c & 0x80); |
$delta = gzuncompress(substr($buf, $pos), $size); |
unset($buf); |
$base_offset = $object_offset - $offset; |
assert($base_offset >= 0); |
list($type, $base) = $this->unpackObject($pack, $base_offset); |
$data = $this->applyDelta($delta, $base); |
} else if ($type == Git::OBJ_REF_DELTA) { |
$base_name = fread($pack, 20); |
list($type, $base) = $this->getRawObject($base_name); |
// $size is the length of the uncompressed delta |
$delta = gzuncompress(fread($pack, $size + 512), $size); |
$data = $this->applyDelta($delta, $base); |
} else |
throw new \Exception(sprintf('object of unknown type %d', $type)); |
return array($type, $data); |
} |
/** |
* @brief Fetch an object in its binary representation by name. |
* |
* Throws an exception if the object cannot be found. |
* |
* @param $object_name (string) name of the object (binary SHA1) |
* @returns (array) an array consisting of the object type (int) and the |
* binary representation of the object (string) |
*/ |
protected function getRawObject($object_name) { |
static $cache = array(); |
/* FIXME allow limiting the cache to a certain size */ |
if (isset($cache[$object_name])) |
return $cache[$object_name]; |
$sha1 = bin2hex($object_name); |
$path = sprintf('%s/objects/%s/%s', $this->dir, substr($sha1, 0, 2), substr($sha1, 2)); |
if (file_exists($path)) { |
list($hdr, $object_data) = explode("\0", gzuncompress(file_get_contents($path)), 2); |
sscanf($hdr, "%s %d", $type, $object_size); |
$object_type = Git::getTypeID($type); |
$r = array($object_type, $object_data); |
} else if ($x = $this->findPackedObject($object_name)) { |
list($pack_name, $object_offset) = $x; |
$pack = fopen(sprintf('%s/objects/pack/pack-%s.pack', $this->dir, bin2hex($pack_name)), 'rb'); |
flock($pack, LOCK_SH); |
/* check magic and version */ |
$magic = fread($pack, 4); |
$version = Binary::fuint32($pack); |
if ($magic != 'PACK' || $version != 2) |
throw new \Exception('unsupported pack format'); |
$r = $this->unpackObject($pack, $object_offset); |
fclose($pack); |
} else |
throw new \Exception(sprintf('object not found: %s', bin2hex($object_name))); |
$cache[$object_name] = $r; |
return $r; |
} |
/** |
* @brief Fetch an object in its PHP representation. |
* |
* @param $name (string) name of the object (binary SHA1) |
* @returns (GitObject) the object |
*/ |
public function getObject($name) { |
list($type, $data) = $this->getRawObject($name); |
$object = GitObject::create($this, $type); |
$object->unserialize($data); |
assert($name == $object->getName()); |
return $object; |
} |
/** |
* @brief Look up a branch. |
* |
* @param $branch (string) The branch to look up, defaulting to @em master. |
* @returns (string) The tip of the branch (binary sha1). |
*/ |
public function getTip($branch = 'master') { |
$subpath = sprintf('refs/heads/%s', $branch); |
$path = sprintf('%s/%s', $this->dir, $subpath); |
if (file_exists($path)) |
return pack('H40', trim(file_get_contents($path))); |
$path = sprintf('%s/packed-refs', $this->dir); |
if (file_exists($path)) { |
$head = null; |
$f = fopen($path, 'rb'); |
flock($f, LOCK_SH); |
while ($head === null && ($line = fgets($f)) !== false) { |
if ($line[0] == '#') |
continue; |
$parts = explode(' ', trim($line)); |
if (count($parts) == 2 && $parts[1] == $subpath) |
$head = pack('H40', $parts[0]);; |
} |
fclose($f); |
if ($head !== null) |
return $head; |
} |
throw new \Exception(sprintf('no such branch: %s', $branch)); |
} |
} |
/trunk/vendor/danielmarschall/glip/src/GitBlob.php |
---|
0,0 → 1,43 |
<?php |
/* |
* Copyright (C) 2008 Patrik Fimml |
* Copyright (c) 2023 Daniel Marschall |
* |
* This file is part of glip. |
* |
* glip is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 2 of the License, or |
* (at your option) any later version. |
* glip is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with glip. If not, see <http://www.gnu.org/licenses/>. |
*/ |
namespace ViaThinkSoft\Glip; |
class GitBlob extends GitObject |
{ |
/** |
* @brief The data contained in this blob. |
*/ |
public $data = null; |
public function __construct($repo) { |
parent::__construct($repo, Git::OBJ_BLOB); |
} |
public function _unserialize($data) { |
$this->data = $data; |
} |
public function _serialize() { |
return $this->data; |
} |
} |
/trunk/vendor/danielmarschall/glip/src/GitCommit.php |
---|
0,0 → 1,164 |
<?php |
/* |
* Copyright (C) 2008, 2009 Patrik Fimml |
* Copyright (c) 2023 Daniel Marschall |
* |
* This file is part of glip. |
* |
* glip is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 2 of the License, or |
* (at your option) any later version. |
* glip is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with glip. If not, see <http://www.gnu.org/licenses/>. |
*/ |
namespace ViaThinkSoft\Glip; |
class GitCommit extends GitObject |
{ |
/** |
* @brief (string) The tree referenced by this commit, as binary sha1 |
* string. |
*/ |
public $tree; |
/** |
* @brief (array of string) Parent commits of this commit, as binary sha1 |
* strings. |
*/ |
public $parents; |
/** |
* @brief (GitCommitStamp) The author of this commit. |
*/ |
public $author; |
/** |
* @brief (GitCommitStamp) The committer of this commit. |
*/ |
public $committer; |
/** |
* @brief (string) Commit summary, i.e. the first line of the commit message. |
*/ |
public $summary; |
/** |
* @brief (string) Everything after the first line of the commit message. |
*/ |
public $detail; |
public $history; |
public function __construct($repo) { |
parent::__construct($repo, Git::OBJ_COMMIT); |
} |
public function _unserialize($data) { |
$lines = explode("\n", $data); |
unset($data); |
$meta = array('parent' => array()); |
while (($line = array_shift($lines)) != '') { |
$parts = explode(' ', $line, 2); |
if (!isset($meta[$parts[0]])) |
$meta[$parts[0]] = array($parts[1]); |
else |
$meta[$parts[0]][] = $parts[1]; |
} |
$this->tree = pack('H40', $meta['tree'][0]); |
$this->parents = array_map(function ($hex) { |
return pack('H40', $hex); |
}, $meta['parent']); |
$this->author = new GitCommitStamp; |
$this->author->unserialize($meta['author'][0]); |
$this->committer = new GitCommitStamp; |
$this->committer->unserialize($meta['committer'][0]); |
$this->summary = array_shift($lines); |
$this->detail = implode("\n", $lines); |
$this->history = null; |
} |
public function _serialize() { |
$s = ''; |
$s .= sprintf("tree %s\n", bin2hex($this->tree)); |
foreach ($this->parents as $parent) |
$s .= sprintf("parent %s\n", bin2hex($parent)); |
$s .= sprintf("author %s\n", $this->author->serialize()); |
$s .= sprintf("committer %s\n", $this->committer->serialize()); |
$s .= "\n" . $this->summary . "\n" . $this->detail; |
return $s; |
} |
/** |
* @brief Get commit history in topological order. |
* |
* @returns (array of GitCommit) |
*/ |
public function getHistory() { |
if ($this->history) |
return $this->history; |
/* count incoming edges */ |
$inc = array(); |
$queue = array($this); |
while (($commit = array_shift($queue)) !== null) { |
foreach ($commit->parents as $parent) { |
if (!isset($inc[$parent])) { |
$inc[$parent] = 1; |
$queue[] = $this->repo->getObject($parent); |
} else |
$inc[$parent]++; |
} |
} |
$queue = array($this); |
$r = array(); |
while (($commit = array_pop($queue)) !== null) { |
array_unshift($r, $commit); |
foreach ($commit->parents as $parent) { |
if (--$inc[$parent] == 0) |
$queue[] = $this->repo->getObject($parent); |
} |
} |
$this->history = $r; |
return $r; |
} |
/** |
* @brief Get the tree referenced by this commit. |
* |
* @returns GitTree The GitTree referenced by this commit. |
*/ |
public function getTree() { |
return $this->repo->getObject($this->tree); |
} |
/** |
* @copybrief GitTree::find() |
* |
* This is a convenience function calling GitTree::find() on the commit's |
* tree. |
* |
* @copydetails GitTree::find() |
*/ |
public function find($path) { |
return $this->getTree()->find($path); |
} |
static public function treeDiff($a, $b) { |
return GitTree::treeDiff($a ? $a->getTree() : null, $b ? $b->getTree() : null); |
} |
} |
/trunk/vendor/danielmarschall/glip/src/GitCommitStamp.php |
---|
0,0 → 1,47 |
<?php |
/* |
* Copyright (C) 2008 Patrik Fimml |
* Copyright (c) 2023 Daniel Marschall |
* |
* This file is part of glip. |
* |
* glip is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 2 of the License, or |
* (at your option) any later version. |
* glip is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with glip. If not, see <http://www.gnu.org/licenses/>. |
*/ |
namespace ViaThinkSoft\Glip; |
class GitCommitStamp |
{ |
public $name; |
public $email; |
public $time; |
public $offset; |
public function unserialize($data) { |
$res = preg_match('/^(.+?)\s+<(.+?)>\s+(\d+)\s+([+-]\d{4})$/', $data, $m); |
assert($res); |
$this->name = $m[1]; |
$this->email = $m[2]; |
$this->time = intval($m[3]); |
$off = intval($m[4]); |
$this->offset = ($off / 100) * 3600 + ($off % 100) * 60; |
} |
public function serialize() { |
if ($this->offset % 60) |
throw new \Exception('cannot serialize sub-minute timezone offset'); |
return sprintf('%s <%s> %d %+05d', $this->name, $this->email, $this->time, ($this->offset / 3600) * 100 + ($this->offset / 60) % 60); |
} |
} |
/trunk/vendor/danielmarschall/glip/src/GitObject.php |
---|
0,0 → 1,154 |
<?php |
/* |
* Copyright (C) 2008 Patrik Fimml |
* Copyright (c) 2023 Daniel Marschall |
* |
* This file is part of glip. |
* |
* glip is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 2 of the License, or |
* (at your option) any later version. |
* glip is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with glip. If not, see <http://www.gnu.org/licenses/>. |
*/ |
namespace ViaThinkSoft\Glip; |
class GitObject |
{ |
/** |
* @brief (Git) The repository this object belongs to. |
*/ |
public $repo; |
protected $type; |
protected $name = null; |
/** |
* @brief Get the object's cached SHA-1 hash value. |
* |
* @returns (string) The hash value (binary sha1). |
*/ |
public function getName() { |
return $this->name; |
} |
/** |
* @brief Get the object's type. |
* |
* @returns (integer) One of Git::OBJ_COMMIT, Git::OBJ_TREE or |
* GIT::OBJ_BLOB. |
*/ |
public function getType() { |
return $this->type; |
} |
/** |
* @brief Create a GitObject of the specified type. |
* |
* @param $repo (Git) The repository the object belongs to. |
* @param $type (integer) Object type (one of Git::OBJ_COMMIT, |
* Git::OBJ_TREE, Git::OBJ_BLOB). |
* @returns GitCommit|GitTree|GitBlob A new GitCommit, GitTree or GitBlob object respectively. |
*/ |
static public function create($repo, $type) { |
if ($type == Git::OBJ_COMMIT) |
return new GitCommit($repo); |
if ($type == Git::OBJ_TREE) |
return new GitTree($repo); |
if ($type == Git::OBJ_BLOB) |
return new GitBlob($repo); |
throw new \Exception(sprintf('unhandled object type %d', $type)); |
} |
/** |
* @brief Internal function to calculate the hash value of a git object of the |
* current type with content $data. |
* |
* @param $data (string) The data to hash. |
* @returns (string) The hash value (binary sha1). |
*/ |
protected function hash($data) { |
$hash = hash_init('sha1'); |
hash_update($hash, Git::getTypeName($this->type)); |
hash_update($hash, ' '); |
hash_update($hash, "".strlen($data)); |
hash_update($hash, "\0"); |
hash_update($hash, $data); |
return hash_final($hash, true); |
} |
/** |
* @brief Internal constructor for use from derived classes. |
* |
* Never use this function except from a derived class. Use the |
* constructor of a derived class, create() or Git::getObject() instead. |
*/ |
public function __construct($repo, $type) { |
$this->repo = $repo; |
$this->type = $type; |
} |
/** |
* @brief Populate this object with values from its string representation. |
* |
* Note that the types of $this and the serialized object in $data have to |
* match. |
* |
* @param $data (string) The serialized representation of an object, as |
* it would be stored by git. |
*/ |
public function unserialize($data) { |
$this->name = $this->hash($data); |
$this->_unserialize($data); |
} |
/** |
* @brief Get the string representation of an object. |
* |
* @returns string The serialized representation of the object, as it would be |
* stored by git. |
*/ |
public function serialize() { |
return $this->_serialize(); |
} |
/** |
* @brief Update the SHA-1 name of an object. |
* |
* You need to call this function after making changes to attributes in |
* order to have getName() return the correct hash. |
*/ |
public function rehash() { |
$this->name = $this->hash($this->serialize()); |
} |
/** |
* @brief Write this object in its serialized form to the git repository |
* given at creation time. |
*/ |
public function write() { |
$sha1 = bin2hex($this->name); |
$path = sprintf('%s/objects/%s/%s', $this->repo->dir, substr($sha1, 0, 2), substr($sha1, 2)); |
if (file_exists($path)) |
return false; |
$dir = dirname($path); |
if (!is_dir($dir)) |
mkdir(dirname($path), 0770); |
$f = fopen($path, 'ab'); |
flock($f, LOCK_EX); |
ftruncate($f, 0); |
$data = $this->serialize(); |
$data = Git::getTypeName($this->type) . ' ' . strlen($data) . "\0" . $data; |
fwrite($f, gzcompress($data)); |
fclose($f); |
return true; |
} |
} |
/trunk/vendor/danielmarschall/glip/src/GitTree.php |
---|
0,0 → 1,233 |
<?php |
/* |
* Copyright (C) 2008, 2009 Patrik Fimml |
* Copyright (c) 2023 Daniel Marschall |
* |
* This file is part of glip. |
* |
* glip is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 2 of the License, or |
* (at your option) any later version. |
* glip is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with glip. If not, see <http://www.gnu.org/licenses/>. |
*/ |
namespace ViaThinkSoft\Glip; |
class GitTree extends GitObject |
{ |
public $nodes = array(); |
public function __construct($repo) { |
parent::__construct($repo, Git::OBJ_TREE); |
} |
public function _unserialize($data) { |
$this->nodes = array(); |
$start = 0; |
while ($start < strlen($data)) { |
$node = new \stdClass; |
$pos = strpos($data, "\0", $start); |
list($node->mode, $node->name) = explode(' ', substr($data, $start, $pos - $start), 2); |
$node->mode = intval($node->mode, 8); |
$node->is_dir = !!($node->mode & 040000); |
$node->is_submodule = ($node->mode == 57344); |
$node->object = substr($data, $pos + 1, 20); |
$start = $pos + 21; |
$this->nodes[$node->name] = $node; |
} |
unset($data); |
} |
protected static function nodecmp(&$a, &$b) { |
return strcmp($a->name, $b->name); |
} |
public function _serialize() { |
$s = ''; |
/* git requires nodes to be sorted */ |
uasort($this->nodes, array('GitTree', 'nodecmp')); |
foreach ($this->nodes as $node) |
$s .= sprintf("%s %s\0%s", base_convert($node->mode, 10, 8), $node->name, $node->object); |
return $s; |
} |
/** |
* @brief Find the tree or blob at a certain path. |
* |
* @param string|array $path The path to look for, relative to this tree. |
* @returns GitTree|GitBlob|null The GitTree or GitBlob at the specified path, or NULL if none |
* could be found. |
* @throws GitTreeInvalidPathError The path was found to be invalid. This |
* can happen if you are trying to treat a file like a directory (i.e. |
* @em foo/bar where @em foo is a file). |
* |
*/ |
public function find($path) { |
if (!is_array($path)) |
$path = explode('/', $path); |
while ($path && !$path[0]) |
array_shift($path); |
if (!$path) |
return $this->getName(); |
if (!isset($this->nodes[$path[0]])) |
return null; |
$cur = $this->nodes[$path[0]]->object; |
array_shift($path); |
while ($path && !$path[0]) |
array_shift($path); |
if (!$path) |
return $cur; |
else { |
$cur = $this->repo->getObject($cur); |
if (!($cur instanceof GitTree)) |
throw new GitTreeInvalidPathError; |
return $cur->find($path); |
} |
} |
/** |
* @brief Recursively list the contents of a tree. |
* |
* @returns (array mapping string to string) An array where the keys are |
* paths relative to the current tree, and the values are SHA-1 names of |
* the corresponding blobs in binary representation. |
*/ |
public function listRecursive() { |
$r = array(); |
foreach ($this->nodes as $node) { |
if ($node->is_dir) { |
if ($node->is_submodule) { |
$r[$node->name . ':submodule'] = $node->object; |
} else { |
$subtree = $this->repo->getObject($node->object); |
foreach ($subtree->listRecursive() as $entry => $blob) { |
$r[$node->name . '/' . $entry] = $blob; |
} |
} |
} else { |
$r[$node->name] = $node->object; |
} |
} |
return $r; |
} |
/** |
* @brief Updates a node in this tree. |
* |
* Missing directories in the path will be created automatically. |
* |
* @param $path (string) Path to the node, relative to this tree. |
* @param $mode Git mode to set the node to. 0 if the node shall be |
* cleared, i.e. the tree or blob shall be removed from this path. |
* @param $object (string) Binary SHA-1 hash of the object that shall be |
* placed at the given path. |
* |
* @returns (array of GitObject) An array of GitObject%s that were newly |
* created while updating the specified node. Those need to be written to |
* the repository together with the modified tree. |
*/ |
public function updateNode($path, $mode, $object) { |
if (!is_array($path)) |
$path = explode('/', $path); |
$name = array_shift($path); |
if (count($path) == 0) { |
/* create leaf node */ |
if ($mode) { |
$node = new \stdClass; |
$node->mode = $mode; |
$node->name = $name; |
$node->object = $object; |
$node->is_dir = !!($mode & 040000); |
$this->nodes[$node->name] = $node; |
} else |
unset($this->nodes[$name]); |
return array(); |
} else { |
/* descend one level */ |
if (isset($this->nodes[$name])) { |
$node = $this->nodes[$name]; |
if (!$node->is_dir) |
throw new GitTreeInvalidPathError; |
$subtree = clone $this->repo->getObject($node->object); |
} else { |
/* create new tree */ |
$subtree = new GitTree($this->repo); |
$node = new \stdClass; |
$node->mode = 040000; |
$node->name = $name; |
$node->is_dir = true; |
$this->nodes[$node->name] = $node; |
} |
$pending = $subtree->updateNode($path, $mode, $object); |
$subtree->rehash(); |
$node->object = $subtree->getName(); |
$pending[] = $subtree; |
return $pending; |
} |
} |
const TREEDIFF_A = 0x01; |
const TREEDIFF_B = 0x02; |
const TREEDIFF_REMOVED = self::TREEDIFF_A; |
const TREEDIFF_ADDED = self::TREEDIFF_B; |
const TREEDIFF_CHANGED = 0x03; |
static public function treeDiff($a_tree, $b_tree) { |
$a_blobs = $a_tree ? $a_tree->listRecursive() : array(); |
$b_blobs = $b_tree ? $b_tree->listRecursive() : array(); |
$a_files = array_keys($a_blobs); |
$b_files = array_keys($b_blobs); |
$changes = array(); |
sort($a_files); |
sort($b_files); |
$a = $b = 0; |
while ($a < count($a_files) || $b < count($b_files)) { |
if ($a < count($a_files) && $b < count($b_files)) |
$cmp = strcmp($a_files[$a], $b_files[$b]); |
else |
$cmp = 0; |
if ($b >= count($b_files) || $cmp < 0) { |
$changes[$a_files[$a]] = self::TREEDIFF_REMOVED; |
$a++; |
} else if ($a >= count($a_files) || $cmp > 0) { |
$changes[$b_files[$b]] = self::TREEDIFF_ADDED; |
$b++; |
} else { |
if ($a_blobs[$a_files[$a]] != $b_blobs[$b_files[$b]]) |
$changes[$a_files[$a]] = self::TREEDIFF_CHANGED; |
$a++; |
$b++; |
} |
} |
return $changes; |
} |
} |
/trunk/vendor/danielmarschall/glip/src/GitTreeError.php |
---|
0,0 → 1,27 |
<?php |
/* |
* Copyright (C) 2008, 2009 Patrik Fimml |
* Copyright (c) 2023 Daniel Marschall |
* |
* This file is part of glip. |
* |
* glip is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 2 of the License, or |
* (at your option) any later version. |
* glip is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with glip. If not, see <http://www.gnu.org/licenses/>. |
*/ |
namespace ViaThinkSoft\Glip; |
class GitTreeError extends \Exception |
{ |
} |
/trunk/vendor/danielmarschall/glip/src/GitTreeInvalidPathError.php |
---|
0,0 → 1,27 |
<?php |
/* |
* Copyright (C) 2008, 2009 Patrik Fimml |
* Copyright (c) 2023 Daniel Marschall |
* |
* This file is part of glip. |
* |
* glip is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 2 of the License, or |
* (at your option) any later version. |
* glip is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with glip. If not, see <http://www.gnu.org/licenses/>. |
*/ |
namespace ViaThinkSoft\Glip; |
class GitTreeInvalidPathError extends GitTreeError |
{ |
} |