Merge pull request #11 from bessl/patch-2
Merge pull request #11 from bessl/patch-2

Update gitphp.po

<?php <?php
/** /**
* Utility function class * Utility function class
* *
* @author Christopher Han <xiphux@gmail.com> * @author Christopher Han <xiphux@gmail.com>
* @copyright Copyright (c) 2010 Christopher Han * @copyright Copyright (c) 2010 Christopher Han
* @package GitPHP * @package GitPHP
*/ */
class GitPHP_Util class GitPHP_Util
{ {
   
/** /**
* Adds a trailing slash to a directory path if necessary * Adds a trailing slash to a directory path if necessary
* *
* @param string $path path to add slash to * @param string $path path to add slash to
* @param boolean $filesystem true if this is a filesystem path (to also check for backslash for windows paths) * @param boolean $filesystem true if this is a filesystem path (to also check for backslash for windows paths)
* @return string path with a trailing slash * @return string path with a trailing slash
*/ */
public static function AddSlash($path, $filesystem = true) public static function AddSlash($path, $filesystem = true)
{ {
if (empty($path)) if (empty($path))
return $path; return $path;
   
$end = substr($path, -1); $end = substr($path, -1);
   
if (!(( ($end == '/') || ($end == ':')) || ($filesystem && GitPHP_Util::IsWindows() && ($end == '\\')))) { if (!(( ($end == '/') || ($end == ':')) || ($filesystem && GitPHP_Util::IsWindows() && ($end == '\\')))) {
if (GitPHP_Util::IsWindows() && $filesystem) { if (GitPHP_Util::IsWindows() && $filesystem) {
$path .= '\\'; $path .= '\\';
} else { } else {
$path .= '/'; $path .= '/';
} }
} }
   
return $path; return $path;
} }
   
/** /**
* Tests if this is running on windows * Tests if this is running on windows
* *
* @return bool true if on windows * @return bool true if on windows
*/ */
public static function IsWindows() public static function IsWindows()
{ {
return (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'); return (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');
} }
   
public static function NullFile() public static function NullFile()
{ {
return self::IsWindows() ? 'NUL' : '/dev/null'; return self::IsWindows() ? 'NUL' : '/dev/null';
} }
   
/** /**
* Tests if this is a 64 bit machine * Tests if this is a 64 bit machine
* *
* @return bool true if on 64 bit * @return bool true if on 64 bit
*/ */
public static function Is64Bit() public static function Is64Bit()
{ {
return (strpos(php_uname('m'), '64') !== false); return (strpos(php_uname('m'), '64') !== false);
} }
   
/** /**
* Turn a string into a filename-friendly slug * Turn a string into a filename-friendly slug
* *
* @param string $str string to slugify * @param string $str string to slugify
* @return string slug * @return string slug
*/ */
public static function MakeSlug($str) public static function MakeSlug($str)
{ {
$from = array( $from = array(
'/' '/&'
); );
$to = array( $to = array(
'-' '--'
); );
return str_replace($from, $to, $str); return str_replace($from, $to, $str);
} }
   
/** /**
* Get the filename of a given path * Get the filename of a given path
* *
* Based on Drupal's basename * Based on Drupal's basename
* *
* @param string $path path * @param string $path path
* @param string $suffix optionally trim this suffix * @param string $suffix optionally trim this suffix
* @return string filename * @return string filename
*/ */
public static function BaseName($path, $suffix = null) public static function BaseName($path, $suffix = null)
{ {
$sep = '/'; $sep = '/';
if (GitPHP_Util::IsWindows()) { if (GitPHP_Util::IsWindows()) {
$sep .= '\\'; $sep .= '\\';
} }
   
$path = rtrim($path, $sep); $path = rtrim($path, $sep);
   
if (!preg_match('@[^' . preg_quote($sep) . ']+$@', $path, $matches)) { if (!preg_match('@[^' . preg_quote($sep) . ']+$@', $path, $matches)) {
return ''; return '';
} }
   
$filename = $matches[0]; $filename = $matches[0];
   
if ($suffix) { if ($suffix) {
$filename = preg_replace('@' . preg_quote($suffix, '@') . '$@', '', $filename); $filename = preg_replace('@' . preg_quote($suffix, '@') . '$@', '', $filename);
} }
return $filename; return $filename;
} }
   
/** /**
* Provides a geshi language for a given filename * Provides a geshi language for a given filename
* *
* @param string $filename file name * @param string $filename file name
* @return string language * @return string language
*/ */
public static function GeshiFilenameToLanguage($filename) public static function GeshiFilenameToLanguage($filename)
{ {
if (strncasecmp($filename, 'Makefile', 8) === 0) { if (strncasecmp($filename, 'Makefile', 8) === 0) {
return 'make'; return 'make';
} }
   
return null; return null;
} }
   
/** /**
* Recurses into a directory and lists files inside * Recurses into a directory and lists files inside
* *
* @param string $dir directory * @param string $dir directory
* @return string[] array of filenames * @return string[] array of filenames
*/ */
public static function ListDir($dir) public static function ListDir($dir)
{ {
$files = array(); $files = array();
if ($dh = opendir($dir)) { if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) { while (($file = readdir($dh)) !== false) {
if (($file == '.') || ($file == '..')) { if (($file == '.') || ($file == '..')) {
continue; continue;
} }
$fullFile = $dir . '/' . $file; $fullFile = $dir . '/' . $file;
if (is_dir($fullFile)) { if (is_dir($fullFile)) {
$subFiles = GitPHP_Util::ListDir($fullFile); $subFiles = GitPHP_Util::ListDir($fullFile);
if (count($subFiles) > 0) { if (count($subFiles) > 0) {
$files = array_merge($files, $subFiles); $files = array_merge($files, $subFiles);
} }
} else { } else {
$files[] = $fullFile; $files[] = $fullFile;
} }
} }
} }
return $files; return $files;
} }
   
/** /**
* Get the base install url (without index) * Get the base install url (without index)
* *
* @param boolean $full true to return full url (include protocol and hostname) * @param boolean $full true to return full url (include protocol and hostname)
* @return string base url * @return string base url
*/ */
public static function BaseUrl($full = false) public static function BaseUrl($full = false)
{ {
$baseurl = $_SERVER['SCRIPT_NAME']; $baseurl = $_SERVER['SCRIPT_NAME'];
if (substr_compare($baseurl, 'index.php', -9) === 0) if (substr_compare($baseurl, 'index.php', -9) === 0)
$baseurl = dirname($baseurl); $baseurl = dirname($baseurl);
if ($full) { if ($full) {
$baseurl = $_SERVER['HTTP_HOST'] . $baseurl; $baseurl = $_SERVER['HTTP_HOST'] . $baseurl;
if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on')) if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on'))
$baseurl = 'https://' . $baseurl; $baseurl = 'https://' . $baseurl;
else else
$baseurl = 'http://' . $baseurl; $baseurl = 'http://' . $baseurl;
} }
if (GitPHP_Util::IsWindows()) if (GitPHP_Util::IsWindows())
$baseurl = rtrim($baseurl, "\\"); $baseurl = rtrim($baseurl, "\\");
return rtrim($baseurl, "/"); return rtrim($baseurl, "/");
} }
   
/** /**
* Tests whether a function is allowed to be called * Tests whether a function is allowed to be called
* *
* @param string $function functio name * @param string $function functio name
* @return true if allowed * @return true if allowed
*/ */
public static function FunctionAllowed($function) public static function FunctionAllowed($function)
{ {
if (empty($function)) if (empty($function))
return false; return false;
   
$disabled = @ini_get('disable_functions'); $disabled = @ini_get('disable_functions');
if (!$disabled) { if (!$disabled) {
// no disabled functions // no disabled functions
// or ini_get is disabled so we can't reliably figure this out // or ini_get is disabled so we can't reliably figure this out
return true; return true;
} }
   
$disabledlist = explode(', ', $disabled); $disabledlist = explode(', ', $disabled);
return !in_array($function, $disabledlist); return !in_array($function, $disabledlist);
} }
   
} }
   
<?php <?php
/** /**
* Handles loading data from raw git objects * Handles loading data from raw git objects
* *
* @author Christopher Han <xiphux@gmail.com> * @author Christopher Han <xiphux@gmail.com>
* @copyright Copyright (c) 2012 Christopher Han * @copyright Copyright (c) 2012 Christopher Han
* @package GitPHP * @package GitPHP
* @subpackage Git * @subpackage Git
*/ */
class GitPHP_GitObjectLoader class GitPHP_GitObjectLoader
{ {
/** /**
* The project * The project
* *
* @var GitPHP_Project * @var GitPHP_Project
*/ */
protected $project; protected $project;
   
/** /**
* The list of packs * The list of packs
* *
* @var GitPHP_Pack[] * @var GitPHP_Pack[]
*/ */
protected $packs = array(); protected $packs = array();
   
/** /**
* Whether packs have been read * Whether packs have been read
* *
* @var boolean * @var boolean
*/ */
protected $packsRead = false; protected $packsRead = false;
   
/** /**
* Constructor * Constructor
* *
* @param GitPHP_Project $project project * @param GitPHP_Project $project project
*/ */
public function __construct($project) public function __construct($project)
{ {
if (!$project) if (!$project)
throw new Exception('Project is required'); throw new Exception('Project is required');
   
$this->project = $project; $this->project = $project;
} }
   
/** /**
* Gets the project * Gets the project
* *
* @return GitPHP_Project project * @return GitPHP_Project project
*/ */
public function GetProject() public function GetProject()
{ {
return $this->project; return $this->project;
} }
   
/** /**
* Gets the raw content of an object * Gets the raw content of an object
* *
* @param string $hash object hash * @param string $hash object hash
* @param int $type returns the object type * @param int $type returns the object type
* @return string object data * @return string object data
*/ */
public function GetObject($hash, &$type = 0) public function GetObject($hash, &$type = 0)
{ {
if (!preg_match('/^[0-9A-Fa-f]{40}$/', $hash)) { if (!preg_match('/^[0-9A-Fa-f]{40}$/', $hash)) {
return false; return false;
} }
   
$autolog = new GitPHP_DebugAutoLog(); if (GitPHP_DebugLog::GetInstance()->GetEnabled())
  $autolog = new GitPHP_DebugAutoLog();
   
// first check if it's unpacked // first check if it's unpacked
$path = $this->project->GetPath() . '/objects/' . substr($hash, 0, 2) . '/' . substr($hash, 2); $path = $this->project->GetPath() . '/objects/' . substr($hash, 0, 2) . '/' . substr($hash, 2);
if (file_exists($path)) { if (file_exists($path)) {
list($header, $data) = explode("\0", gzuncompress(file_get_contents($path)), 2); list($header, $data) = explode("\0", gzuncompress(file_get_contents($path)), 2);
if (preg_match('/^([A-Za-z]+) /', $header, $typestr)) { if (preg_match('/^([A-Za-z]+) /', $header, $typestr)) {
switch ($typestr[1]) { switch ($typestr[1]) {
case 'commit': case 'commit':
$type = GitPHP_Pack::OBJ_COMMIT; $type = GitPHP_Pack::OBJ_COMMIT;
break; break;
case 'tree': case 'tree':
$type = GitPHP_Pack::OBJ_TREE; $type = GitPHP_Pack::OBJ_TREE;
break; break;
case 'blob': case 'blob':
$type = GitPHP_Pack::OBJ_BLOB; $type = GitPHP_Pack::OBJ_BLOB;
break; break;
case 'tag': case 'tag':
$type = GitPHP_Pack::OBJ_TAG; $type = GitPHP_Pack::OBJ_TAG;
break; break;
} }
} }
return $data; return $data;
} }
   
if (!$this->packsRead) { if (!$this->packsRead) {
$this->ReadPacks(); $this->ReadPacks();
} }
   
// then try packs // then try packs
foreach ($this->packs as $pack) { foreach ($this->packs as $pack) {
$data = $pack->GetObject($hash, $type); $data = $pack->GetObject($hash, $type);
if ($data !== false) { if ($data !== false) {
return $data; return $data;
} }
} }
   
return false; return false;
} }
   
/** /**
* Read the list of packs in the repository * Read the list of packs in the repository
*/ */
private function ReadPacks() private function ReadPacks()
{ {
$dh = opendir($this->project->GetPath() . '/objects/pack'); $dh = opendir($this->project->GetPath() . '/objects/pack');
if ($dh !== false) { if ($dh !== false) {
while (($file = readdir($dh)) !== false) { while (($file = readdir($dh)) !== false) {
if (preg_match('/^pack-([0-9A-Fa-f]{40})\.pack$/', $file, $regs)) { if (preg_match('/^pack-([0-9A-Fa-f]{40})\.pack$/', $file, $regs)) {
$this->packs[] = new GitPHP_Pack($this->project, $regs[1], $this); $this->packs[] = new GitPHP_Pack($this->project, $regs[1], $this);
} }
} }
} }
$this->packsRead = true; $this->packsRead = true;
} }
   
/** /**
* Ensures a hash prefix is unique * Ensures a hash prefix is unique
* *
* @param string $hash full hash * @param string $hash full hash
* @param string $prefix abbreviated hash prefix * @param string $prefix abbreviated hash prefix
*/ */
public function EnsureUniqueHash($hash, $prefix) public function EnsureUniqueHash($hash, $prefix)
{ {
if (empty($hash) || empty($prefix)) if (empty($hash) || empty($prefix))
return null; return null;
   
if (!(preg_match('/[0-9A-Fa-f]{40}/', $hash))) if (!(preg_match('/[0-9A-Fa-f]{40}/', $hash)))
return $hash; return $hash;
   
if (preg_match('/[0-9A-Fa-f]{40}/', $prefix)) if (preg_match('/[0-9A-Fa-f]{40}/', $prefix))
return $prefix; return $prefix;
   
$hashMap = array(); $hashMap = array();
   
$matches = $this->FindHashObjects($prefix); $matches = $this->FindHashObjects($prefix);
foreach ($matches as $matchingHash) { foreach ($matches as $matchingHash) {
$hashMap[$matchingHash] = 1; $hashMap[$matchingHash] = 1;
} }
   
if (!$this->packsRead) { if (!$this->packsRead) {
$this->ReadPacks(); $this->ReadPacks();
} }
   
foreach ($this->packs as $pack) { foreach ($this->packs as $pack) {
$matches = $pack->FindHashes($prefix); $matches = $pack->FindHashes($prefix);
foreach ($matches as $matchingHash) { foreach ($matches as $matchingHash) {
$hashMap[$matchingHash] = 1; $hashMap[$matchingHash] = 1;
} }
} }
   
if (count($hashMap) == 0) { if (count($hashMap) == 0) {
return $hash; return $hash;
} }
   
if (count($hashMap) == 1) { if (count($hashMap) == 1) {
return $prefix; return $prefix;
} }
   
for ($len = strlen($prefix)+1; $len < 40; $len++) { for ($len = strlen($prefix)+1; $len < 40; $len++) {
$prefix = substr($hash, 0, $len); $prefix = substr($hash, 0, $len);
   
foreach (array_keys($hashMap) as $matchingHash) { foreach (array_keys($hashMap) as $matchingHash) {
if (substr_compare($matchingHash, $prefix, 0, $len) !== 0) { if (substr_compare($matchingHash, $prefix, 0, $len) !== 0) {
unset($hashMap[$matchingHash]); unset($hashMap[$matchingHash]);
} }
} }
   
if (count($hashMap) == 1) { if (count($hashMap) == 1) {
return $prefix; return $prefix;
} }
} }
   
return $hash; return $hash;
} }
   
/** /**
* Expands an abbreviated hash to the full hash * Expands an abbreviated hash to the full hash
* *
* @param string $abbrevHash abbreviated hash * @param string $abbrevHash abbreviated hash
* @return string full hash * @return string full hash
*/ */
public function ExpandHash($abbrevHash) public function ExpandHash($abbrevHash)
{ {
if (!(preg_match('/[0-9A-Fa-f]{4,39}/', $abbrevHash))) { if (!(preg_match('/[0-9A-Fa-f]{4,39}/', $abbrevHash))) {
return $abbrevHash; return $abbrevHash;
} }
   
$matches = $this->FindHashObjects($abbrevHash); $matches = $this->FindHashObjects($abbrevHash);
   
if (!$this->packsRead) { if (!$this->packsRead) {
$this->ReadPacks(); $this->ReadPacks();
} }
   
foreach ($this->packs as $pack) { foreach ($this->packs as $pack) {
$matches = array_merge($matches, $pack->FindHashes($abbrevHash)); $matches = array_merge($matches, $pack->FindHashes($abbrevHash));
} }
   
$matches = array_unique($matches); $matches = array_unique($matches);
   
if (count($matches) < 1) if (count($matches) < 1)
return $abbrevHash; return $abbrevHash;
   
if (count($matches) > 1) { if (count($matches) > 1) {
throw new GitPHP_AmbiguousHashException($abbrevHash); throw new GitPHP_AmbiguousHashException($abbrevHash);
} }
   
return $matches[0]; return $matches[0];
} }
   
/** /**
* Finds loose hash files matching a given prefix * Finds loose hash files matching a given prefix
* *
* @param string $prefix hash prefix * @param string $prefix hash prefix
* @return string[] array of hashes * @return string[] array of hashes
*/ */
private function FindHashObjects($prefix) private function FindHashObjects($prefix)
{ {
$matches = array(); $matches = array();
if (empty($prefix)) { if (empty($prefix)) {
return $matches; return $matches;
} }
   
$subdir = substr($prefix, 0, 2); $subdir = substr($prefix, 0, 2);
$fulldir = $this->project->GetPath() . '/objects/' . $subdir; $fulldir = $this->project->GetPath() . '/objects/' . $subdir;
if (!is_dir($fulldir)) { if (!is_dir($fulldir)) {
return $matches; return $matches;
} }
   
$prefixlen = strlen($prefix); $prefixlen = strlen($prefix);
$dh = opendir($fulldir); $dh = opendir($fulldir);
if ($dh !== false) { if ($dh !== false) {
while (($file = readdir($dh)) !== false) { while (($file = readdir($dh)) !== false) {
$fullhash = $subdir . $file; $fullhash = $subdir . $file;
if (substr_compare($fullhash, $prefix, 0, $prefixlen) === 0) { if (substr_compare($fullhash, $prefix, 0, $prefixlen) === 0) {
$matches[] = $fullhash; $matches[] = $fullhash;
} }
} }
} }
return $matches; return $matches;
} }
   
} }
   
<?php <?php
/** /**
* Bzip2 archive creation class * Bzip2 archive creation class
* *
* @author Christopher Han <xiphux@gmail.com> * @author Christopher Han <xiphux@gmail.com>
* @copyright Copyright (c) 2012 Christopher Han * @copyright Copyright (c) 2012 Christopher Han
* @package GitPHP * @package GitPHP
* @subpackage Git\Archive * @subpackage Git\Archive
*/ */
class GitPHP_Archive_Bzip2 implements GitPHP_ArchiveStrategy_Interface class GitPHP_Archive_Bzip2 implements GitPHP_ArchiveStrategy_Interface
{ {
/** /**
* Executable * Executable
* *
* @var GitPHP_GitExe * @var GitPHP_GitExe
*/ */
protected $exe; protected $exe;
   
/** /**
* Process handle * Process handle
* *
* @var resource * @var resource
*/ */
protected $handle; protected $handle;
   
/** /**
* Compression level * Compression level
* *
* @var integer * @var integer
*/ */
protected $compressLevel; protected $compressLevel;
   
/** /**
* Constructor * Constructor
* *
* @param integer $compressLevel compression level * @param integer $compressLevel compression level
*/ */
public function __construct($compressLevel = null) public function __construct($compressLevel = null)
{ {
if (!(($compressLevel === null) || (is_int($compressLevel) && ($compressLevel >= 1) && ($compressLevel <= 9)))) if (!(($compressLevel === null) || (is_int($compressLevel) && ($compressLevel >= 1) && ($compressLevel <= 9))))
throw new Exception('Invalid compression level'); throw new Exception('Invalid compression level');
   
$this->compressLevel = $compressLevel; $this->compressLevel = $compressLevel;
} }
   
/** /**
* Set executable for this archive * Set executable for this archive
* *
* @param GitPHP_GitExe $exe git exe * @param GitPHP_GitExe $exe git exe
*/ */
public function SetExe($exe) public function SetExe($exe)
{ {
$this->exe = $exe; $this->exe = $exe;
} }
   
/** /**
* Open a descriptor for this archive * Open a descriptor for this archive
* *
* @param GitPHP_Archive $archive archive * @param GitPHP_Archive $archive archive
* @return boolean true on success * @return boolean true on success
*/ */
public function Open($archive) public function Open($archive)
{ {
if (!$archive) if (!$archive)
return false; return false;
   
if ($this->handle) { if ($this->handle) {
return true; return true;
} }
   
$args = array(); $args = array();
$args[] = '--format=tar'; $args[] = '--format=tar';
$args[] = '--prefix=' . $archive->GetPrefix(); $args[] = "--prefix='" . $archive->GetPrefix() . "'";
$args[] = $archive->GetObject()->GetHash(); $args[] = $archive->GetObject()->GetHash();
   
$this->handle = $this->exe->Open($archive->GetProject()->GetPath(), GIT_ARCHIVE, $args); $this->handle = $this->exe->Open($archive->GetProject()->GetPath(), GIT_ARCHIVE, $args);
   
return ($this->handle !== false); return ($this->handle !== false);
} }
   
/** /**
* Read a chunk of the archive data * Read a chunk of the archive data
* *
* @param int $size size of data to read * @param int $size size of data to read
* @return string|boolean archive data or false * @return string|boolean archive data or false
*/ */
public function Read($size = 1048576) public function Read($size = 1048576)
{ {
if (!$this->handle) if (!$this->handle)
return false; return false;
   
if (feof($this->handle)) if (feof($this->handle))
return false; return false;
   
$data = fread($this->handle, $size); $data = fread($this->handle, $size);
   
if ($this->compressLevel) if ($this->compressLevel)
return bzcompress($data, $this->compressLevel); return bzcompress($data, $this->compressLevel);
else else
return bzcompress($data); return bzcompress($data);
} }
   
/** /**
* Close archive descriptor * Close archive descriptor
*/ */
public function Close() public function Close()
{ {
if (!$this->handle) if (!$this->handle)
return true; return true;
   
pclose($this->handle); pclose($this->handle);
   
$this->handle = null; $this->handle = null;
   
return true; return true;
} }
   
/** /**
* Gets the file extension for this format * Gets the file extension for this format
* *
* @return string extension * @return string extension
*/ */
public function Extension() public function Extension()
{ {
return 'tar.bz2'; return 'tar.bz2';
} }
   
/** /**
* Gets the mime type for this format * Gets the mime type for this format
* *
* @return string mime type * @return string mime type
*/ */
public function MimeType() public function MimeType()
{ {
return 'application/x-bzip2'; return 'application/x-bzip2';
} }
   
/** /**
* Gets whether this archiver is valid * Gets whether this archiver is valid
* *
* @return boolean true if valid * @return boolean true if valid
*/ */
public function Valid() public function Valid()
{ {
return function_exists('bzcompress'); return function_exists('bzcompress');
} }
} }
   
<?php <?php
/** /**
* Gzip archive creation class * Gzip archive creation class
* *
* @author Christopher Han <xiphux@gmail.com> * @author Christopher Han <xiphux@gmail.com>
* @copyright Copyright (c) 2012 Christopher Han * @copyright Copyright (c) 2012 Christopher Han
* @package GitPHP * @package GitPHP
* @subpackage Git\Archive * @subpackage Git\Archive
*/ */
class GitPHP_Archive_Gzip implements GitPHP_ArchiveStrategy_Interface class GitPHP_Archive_Gzip implements GitPHP_ArchiveStrategy_Interface
{ {
/** /**
* Executable * Executable
* *
* @var GitPHP_GitExe * @var GitPHP_GitExe
*/ */
protected $exe; protected $exe;
   
/** /**
* Process handle * Process handle
* *
* @var resource * @var resource
*/ */
protected $handle; protected $handle;
   
/** /**
* Compression level * Compression level
* *
* @var integer * @var integer
*/ */
protected $compressLevel; protected $compressLevel;
   
/** /**
* Temporary file name * Temporary file name
* *
* @var string * @var string
*/ */
protected $tempfile; protected $tempfile;
   
/** /**
* Constructor * Constructor
* *
* @param integer $compressLevel compression level * @param integer $compressLevel compression level
*/ */
public function __construct($compressLevel = null) public function __construct($compressLevel = null)
{ {
if (!(($compressLevel === null) || (is_int($compressLevel) && ($compressLevel >= 1) && ($compressLevel <= 9)))) if (!(($compressLevel === null) || (is_int($compressLevel) && ($compressLevel >= 1) && ($compressLevel <= 9))))
throw new Exception('Invalid compression level'); throw new Exception('Invalid compression level');
   
$this->compressLevel = $compressLevel; $this->compressLevel = $compressLevel;
} }
   
/** /**
* Set executable for this archive * Set executable for this archive
* *
* @param GitPHP_GitExe $exe git exe * @param GitPHP_GitExe $exe git exe
*/ */
public function SetExe($exe) public function SetExe($exe)
{ {
$this->exe = $exe; $this->exe = $exe;
} }
   
/** /**
* Open a descriptor for this archive * Open a descriptor for this archive
* *
* @param GitPHP_Archive $archive archive * @param GitPHP_Archive $archive archive
* @return boolean true on success * @return boolean true on success
*/ */
public function Open($archive) public function Open($archive)
{ {
if (!$archive) if (!$archive)
return false; return false;
   
if ($this->handle) { if ($this->handle) {
return true; return true;
} }
   
$args = array(); $args = array();
$args[] = '--format=tar'; $args[] = '--format=tar';
$args[] = '--prefix=' . $archive->GetPrefix(); $args[] = "--prefix='" . $archive->GetPrefix() . "'";
$args[] = $archive->GetObject()->GetHash(); $args[] = $archive->GetObject()->GetHash();
   
$this->handle = $this->exe->Open($archive->GetProject()->GetPath(), GIT_ARCHIVE, $args); $this->handle = $this->exe->Open($archive->GetProject()->GetPath(), GIT_ARCHIVE, $args);
   
// hack to get around the fact that gzip files // hack to get around the fact that gzip files
// can't be compressed on the fly and the php zlib stream // can't be compressed on the fly and the php zlib stream
// doesn't seem to daisy chain with any non-file streams // doesn't seem to daisy chain with any non-file streams
   
$this->tempfile = tempnam(sys_get_temp_dir(), "GitPHP"); $this->tempfile = tempnam(sys_get_temp_dir(), "GitPHP");
   
$mode = 'wb'; $mode = 'wb';
if ($this->compressLevel) if ($this->compressLevel)
$mode .= $this->compressLevel; $mode .= $this->compressLevel;
   
$temphandle = gzopen($this->tempfile, $mode); $temphandle = gzopen($this->tempfile, $mode);
if ($temphandle) { if ($temphandle) {
while (!feof($this->handle)) { while (!feof($this->handle)) {
gzwrite($temphandle, fread($this->handle, 1048576)); gzwrite($temphandle, fread($this->handle, 1048576));
} }
gzclose($temphandle); gzclose($temphandle);
   
$temphandle = fopen($this->tempfile, 'rb'); $temphandle = fopen($this->tempfile, 'rb');
} }
if ($this->handle) { if ($this->handle) {
pclose($this->handle); pclose($this->handle);
} }
   
$this->handle = $temphandle; $this->handle = $temphandle;
   
return ($this->handle !== false); return ($this->handle !== false);
} }
   
/** /**
* Read a chunk of the archive data * Read a chunk of the archive data
* *
* @param int $size size of data to read * @param int $size size of data to read
* @return string|boolean archive data or false * @return string|boolean archive data or false
*/ */
public function Read($size = 1048576) public function Read($size = 1048576)
{ {
if (!$this->handle) if (!$this->handle)
return false; return false;
   
if (feof($this->handle)) if (feof($this->handle))
return false; return false;
   
return fread($this->handle, $size); return fread($this->handle, $size);
} }
   
/** /**
* Close archive descriptor * Close archive descriptor
*/ */
public function Close() public function Close()
{ {
if (!$this->handle) if (!$this->handle)
return true; return true;
   
fclose($this->handle); fclose($this->handle);
if (!empty($this->tempfile)) { if (!empty($this->tempfile)) {
unlink($this->tempfile); unlink($this->tempfile);
$this->tempfile = ''; $this->tempfile = '';
} }
   
$this->handle = null; $this->handle = null;
   
return true; return true;
} }
   
/** /**
* Gets the file extension for this format * Gets the file extension for this format
* *
* @return string extension * @return string extension
*/ */
public function Extension() public function Extension()
{ {
return 'tar.gz'; return 'tar.gz';
} }
   
/** /**
* Gets the mime type for this format * Gets the mime type for this format
* *
* @return string mime type * @return string mime type
*/ */
public function MimeType() public function MimeType()
{ {
return 'application/x-gzip'; return 'application/x-gzip';
} }
   
/** /**
* Gets whether this archiver is valid * Gets whether this archiver is valid
* *
* @return boolean true if valid * @return boolean true if valid
*/ */
public function Valid() public function Valid()
{ {
return function_exists('gzencode'); return function_exists('gzencode');
} }
} }
   
<?php <?php
/** /**
* Tar archive creation class * Tar archive creation class
* *
* @author Christopher Han <xiphux@gmail.com> * @author Christopher Han <xiphux@gmail.com>
* @copyright Copyright (c) 2012 Christopher Han * @copyright Copyright (c) 2012 Christopher Han
* @package GitPHP * @package GitPHP
* @subpackage Git\Archive * @subpackage Git\Archive
*/ */
class GitPHP_Archive_Tar implements GitPHP_ArchiveStrategy_Interface class GitPHP_Archive_Tar implements GitPHP_ArchiveStrategy_Interface
{ {
/** /**
* Executable * Executable
* *
* @var GitPHP_GitExe * @var GitPHP_GitExe
*/ */
protected $exe; protected $exe;
   
/** /**
* Process handle * Process handle
* *
* @var resource * @var resource
*/ */
protected $handle; protected $handle;
   
/** /**
* Set executable for this archive * Set executable for this archive
* *
* @param GitPHP_GitExe $exe git exe * @param GitPHP_GitExe $exe git exe
*/ */
public function SetExe($exe) public function SetExe($exe)
{ {
$this->exe = $exe; $this->exe = $exe;
} }
   
/** /**
* Open a descriptor for this archive * Open a descriptor for this archive
* *
* @param GitPHP_Archive $archive archive * @param GitPHP_Archive $archive archive
* @return boolean true on success * @return boolean true on success
*/ */
public function Open($archive) public function Open($archive)
{ {
if (!$archive) if (!$archive)
return false; return false;
   
if ($this->handle) { if ($this->handle) {
return true; return true;
} }
   
$args = array(); $args = array();
$args[] = '--format=tar'; $args[] = '--format=tar';
$args[] = '--prefix=' . $archive->GetPrefix(); $args[] = "--prefix='" . $archive->GetPrefix() . "'";
$args[] = $archive->GetObject()->GetHash(); $args[] = $archive->GetObject()->GetHash();
   
$this->handle = $this->exe->Open($archive->GetProject()->GetPath(), GIT_ARCHIVE, $args); $this->handle = $this->exe->Open($archive->GetProject()->GetPath(), GIT_ARCHIVE, $args);
   
return ($this->handle !== false); return ($this->handle !== false);
} }
   
/** /**
* Read a chunk of the archive data * Read a chunk of the archive data
* *
* @param int $size size of data to read * @param int $size size of data to read
* @return string|boolean archive data or false * @return string|boolean archive data or false
*/ */
public function Read($size = 1048576) public function Read($size = 1048576)
{ {
if (!$this->handle) if (!$this->handle)
return false; return false;
   
if (feof($this->handle)) if (feof($this->handle))
return false; return false;
   
return fread($this->handle, $size); return fread($this->handle, $size);
} }
   
/** /**
* Close archive descriptor * Close archive descriptor
*/ */
public function Close() public function Close()
{ {
if (!$this->handle) if (!$this->handle)
return true; return true;
   
pclose($this->handle); pclose($this->handle);
   
$this->handle = null; $this->handle = null;
   
return true; return true;
} }
   
/** /**
* Gets the file extension for this format * Gets the file extension for this format
* *
* @return string extension * @return string extension
*/ */
public function Extension() public function Extension()
{ {
return 'tar'; return 'tar';
} }
   
/** /**
* Gets the mime type for this format * Gets the mime type for this format
* *
* @return string mime type * @return string mime type
*/ */
public function MimeType() public function MimeType()
{ {
return 'application/x-tar'; return 'application/x-tar';
} }
   
/** /**
* Gets whether this archiver is valid * Gets whether this archiver is valid
* *
* @return boolean true if valid * @return boolean true if valid
*/ */
public function Valid() public function Valid()
{ {
return true; return true;
} }
} }
   
<?php <?php
/** /**
* Zip archive creation class * Zip archive creation class
* *
* @author Christopher Han <xiphux@gmail.com> * @author Christopher Han <xiphux@gmail.com>
* @copyright Copyright (c) 2012 Christopher Han * @copyright Copyright (c) 2012 Christopher Han
* @package GitPHP * @package GitPHP
* @subpackage Git\Archive * @subpackage Git\Archive
*/ */
class GitPHP_Archive_Zip implements GitPHP_ArchiveStrategy_Interface class GitPHP_Archive_Zip implements GitPHP_ArchiveStrategy_Interface
{ {
/** /**
* Executable * Executable
* *
* @var GitPHP_GitExe * @var GitPHP_GitExe
*/ */
protected $exe; protected $exe;
   
/** /**
* Process handle * Process handle
* *
* @var resource * @var resource
*/ */
protected $handle; protected $handle;
   
/** /**
* Compression level * Compression level
* *
* @var integer * @var integer
*/ */
protected $compressLevel; protected $compressLevel;
   
/** /**
* Constructor * Constructor
* *
* @param integer $compressLevel compression level * @param integer $compressLevel compression level
*/ */
public function __construct($compressLevel = null) public function __construct($compressLevel = null)
{ {
if (!(($compressLevel === null) || (is_int($compressLevel) && ($compressLevel >= 1) && ($compressLevel <= 9)))) if (!(($compressLevel === null) || (is_int($compressLevel) && ($compressLevel >= 1) && ($compressLevel <= 9))))
throw new Exception('Invalid compression level'); throw new Exception('Invalid compression level');
   
$this->compressLevel = $compressLevel; $this->compressLevel = $compressLevel;
} }
   
/** /**
* Set executable for this archive * Set executable for this archive
* *
* @param GitPHP_GitExe $exe git exe * @param GitPHP_GitExe $exe git exe
*/ */
public function SetExe($exe) public function SetExe($exe)
{ {
$this->exe = $exe; $this->exe = $exe;
} }
   
/** /**
* Open a descriptor for this archive * Open a descriptor for this archive
* *
* @param GitPHP_Archive $archive archive * @param GitPHP_Archive $archive archive
* @return boolean true on success * @return boolean true on success
*/ */
public function Open($archive) public function Open($archive)
{ {
if (!$archive) if (!$archive)
return false; return false;
   
if ($this->handle) { if ($this->handle) {
return true; return true;
} }
   
$args = array(); $args = array();
$args[] = '--format=zip'; $args[] = '--format=zip';
if ($this->compressLevel) if ($this->compressLevel)
$args[] = '-' . $this->compressLevel; $args[] = '-' . $this->compressLevel;
$args[] = '--prefix=' . $archive->GetPrefix(); $args[] = "--prefix='" . $archive->GetPrefix() . "'";
$args[] = $archive->GetObject()->GetHash(); $args[] = $archive->GetObject()->GetHash();
   
$this->handle = $this->exe->Open($archive->GetProject()->GetPath(), GIT_ARCHIVE, $args); $this->handle = $this->exe->Open($archive->GetProject()->GetPath(), GIT_ARCHIVE, $args);
   
return ($this->handle !== false); return ($this->handle !== false);
} }
   
/** /**
* Read a chunk of the archive data * Read a chunk of the archive data
* *
* @param int $size size of data to read * @param int $size size of data to read
* @return string|boolean archive data or false * @return string|boolean archive data or false
*/ */
public function Read($size = 1048576) public function Read($size = 1048576)
{ {
if (!$this->handle) if (!$this->handle)
return false; return false;
   
if (feof($this->handle)) if (feof($this->handle))
return false; return false;
   
return fread($this->handle, $size); return fread($this->handle, $size);
} }
   
/** /**
* Close archive descriptor * Close archive descriptor
*/ */
public function Close() public function Close()
{ {
if (!$this->handle) if (!$this->handle)
return true; return true;
   
pclose($this->handle); pclose($this->handle);
   
$this->handle = null; $this->handle = null;
   
return true; return true;
} }
   
/** /**
* Gets the file extension for this format * Gets the file extension for this format
* *
* @return string extension * @return string extension
*/ */
public function Extension() public function Extension()
{ {
return 'zip'; return 'zip';
} }
   
/** /**
* Gets the mime type for this format * Gets the mime type for this format
* *
* @return string mime type * @return string mime type
*/ */
public function MimeType() public function MimeType()
{ {
return 'application/x-zip'; return 'application/x-zip';
} }
   
/** /**
* Gets whether this archiver is valid * Gets whether this archiver is valid
* *
* @return boolean true if valid * @return boolean true if valid
*/ */
public function Valid() public function Valid()
{ {
// TODO check for git > 1.4.3 for zip // TODO check for git > 1.4.3 for zip
return true; return true;
} }
} }
   
<?php <?php
/** /**
* Head list load strategy using raw objects * Head list load strategy using raw objects
* *
* @author Christopher Han <xiphux@gmail.com> * @author Christopher Han <xiphux@gmail.com>
* @copyright Copyright (c) 2012 Christopher Han * @copyright Copyright (c) 2012 Christopher Han
* @package GitPHP * @package GitPHP
* @subpackage Git\HeadList * @subpackage Git\HeadList
*/ */
class GitPHP_HeadListLoad_Raw extends GitPHP_RefListLoad_Raw implements GitPHP_HeadListLoadStrategy_Interface class GitPHP_HeadListLoad_Raw extends GitPHP_RefListLoad_Raw implements GitPHP_HeadListLoadStrategy_Interface
{ {
/** /**
* Loads the head list * Loads the head list
* *
* @param GitPHP_HeadList $headList head list * @param GitPHP_HeadList $headList head list
* @return array array of head hashes * @return array array of head hashes
*/ */
public function Load($headList) public function Load($headList)
{ {
return $this->GetRefs($headList, 'heads'); return $this->GetRefs($headList, 'heads');
} }
   
/** /**
* Loads sorted heads * Loads sorted heads
* *
* @param GitPHP_HeadList $headList head list * @param GitPHP_HeadList $headList head list
* @param string $order list order * @param string $order list order
* @param integer $count number to load * @param integer $count number to load
* @param integer $skip number to skip * @param integer $skip number to skip
*/ */
public function LoadOrdered($headList, $order, $count = 0, $skip = 0) public function LoadOrdered($headList, $order, $count = 0, $skip = 0)
{ {
if (!$headList) if (!$headList)
return; return;
   
if (empty($order)) if (empty($order))
return; return;
   
$autotimer = new GitPHP_DebugAutoLog(); if (GitPHP_DebugLog::GetInstance()->GetEnabled())
  $autotimer = new GitPHP_DebugAutoLog();
   
$heads = $headList->GetHeads(); $heads = $headList->GetHeads();
   
/* TODO add different orders */ /* TODO add different orders */
if ($order == '-committerdate') { if ($order == '-committerdate') {
@usort($heads, array('GitPHP_Head', 'CompareAge')); @usort($heads, array('GitPHP_Head', 'CompareAge'));
} }
   
if ((($count > 0) && (count($heads) > $count)) || ($skip > 0)) { if ((($count > 0) && (count($heads) > $count)) || ($skip > 0)) {
if ($count > 0) if ($count > 0)
$heads = array_slice($heads, $skip, $count); $heads = array_slice($heads, $skip, $count);
else else
$heads = array_slice($heads, $skip); $heads = array_slice($heads, $skip);
} }
   
return $heads; return $heads;
} }
} }
   
<?php <?php
/** /**
* Lists all projects in a given file * Lists all projects in a given file
* *
* @author Christopher Han <xiphux@gmail.com> * @author Christopher Han <xiphux@gmail.com>
* @copyright Copyright (c) 2010 Christopher Han * @copyright Copyright (c) 2010 Christopher Han
* @package GitPHP * @package GitPHP
* @subpackage Git\ProjectList * @subpackage Git\ProjectList
*/ */
class GitPHP_ProjectListFile extends GitPHP_ProjectListBase class GitPHP_ProjectListFile extends GitPHP_ProjectListBase
{ {
   
/** /**
* The contents of the project list file * The contents of the project list file
* *
* @var string[] * @var string[]
*/ */
protected $fileContents = array(); protected $fileContents = array();
   
/** /**
* Whether the file has been read * Whether the file has been read
* *
* @var boolean * @var boolean
*/ */
protected $fileRead = false; protected $fileRead = false;
/** /**
* constructor * constructor
* *
* @param string $projectRoot project root * @param string $projectRoot project root
* @param string $projectFile file to read * @param string $projectFile file to read
* @throws Exception if parameter is not a readable file * @throws Exception if parameter is not a readable file
*/ */
public function __construct($projectRoot, $projectFile) public function __construct($projectRoot, $projectFile)
{ {
if (!(is_string($projectFile) && is_file($projectFile))) { if (!(is_string($projectFile) && is_file($projectFile))) {
throw new GitPHP_InvalidFileException($projectFile); throw new GitPHP_InvalidFileException($projectFile);
} }
   
$this->projectConfig = $projectFile; $this->projectConfig = $projectFile;
   
parent::__construct($projectRoot); parent::__construct($projectRoot);
} }
   
/** /**
* Populates the internal list of projects * Populates the internal list of projects
*/ */
protected function PopulateProjects() protected function PopulateProjects()
{ {
if (!$this->fileRead) if (!$this->fileRead)
$this->ReadFile(); $this->ReadFile();
   
foreach ($this->fileContents as $lineData) { foreach ($this->fileContents as $lineData) {
if (isset($lineData['project'])) { if (isset($lineData['project'])) {
$projObj = $this->LoadProject($lineData['project']); $projObj = $this->LoadProject($lineData['project']);
if ($projObj) { if ($projObj) {
$this->projects[$lineData['project']] = $projObj; $this->projects[$lineData['project']] = $projObj;
unset($projObj); unset($projObj);
} }
} }
} }
} }
   
/** /**
* Loads a project * Loads a project
* *
* @param string $proj project * @param string $proj project
* @return GitPHP_Project project object * @return GitPHP_Project project object
*/ */
protected function LoadProject($proj) protected function LoadProject($proj)
{ {
if (!$this->fileRead) if (!$this->fileRead)
$this->ReadFile(); $this->ReadFile();
   
$found = false; $found = false;
$owner = null; $owner = null;
foreach ($this->fileContents as $lineData) { foreach ($this->fileContents as $lineData) {
if (isset($lineData['project']) && ($lineData['project'] == $proj)) { if (isset($lineData['project']) && ($lineData['project'] == $proj)) {
$projectRoot = GitPHP_Util::AddSlash($this->projectRoot); $projectRoot = GitPHP_Util::AddSlash($this->projectRoot);
if (is_file($projectRoot . $proj . '/HEAD')) { if (is_file($projectRoot . $proj . '/HEAD')) {
$found = true; $found = true;
if (isset($lineData['owner'])) { if (isset($lineData['owner'])) {
$owner = $lineData['owner']; $owner = $lineData['owner'];
} }
} else { } else {
$this->Log('Invalid project', $projectRoot . $proj); $this->Log('Invalid project', $projectRoot . $proj);
} }
break; break;
} }
} }
   
if (!$found) if (!$found)
return null; return null;
   
$projectObj = new GitPHP_Project($this->projectRoot, $proj); $projectObj = new GitPHP_Project($this->projectRoot, $proj);
   
$this->ApplyGlobalConfig($projectObj); $this->ApplyGlobalConfig($projectObj);
   
$this->ApplyGitConfig($projectObj); $this->ApplyGitConfig($projectObj);
   
if (!empty($owner)) if (!empty($owner))
$projectObj->SetOwner($owner); $projectObj->SetOwner($owner);
   
if ($this->projectSettings && isset($this->projectSettings[$proj])) { if ($this->projectSettings && isset($this->projectSettings[$proj])) {
$this->ApplyProjectSettings($projectObj, $this->projectSettings[$proj]); $this->ApplyProjectSettings($projectObj, $this->projectSettings[$proj]);
} }
   
$this->InjectProjectDependencies($projectObj); $this->InjectProjectDependencies($projectObj);
   
return $projectObj; return $projectObj;
} }
   
/** /**
* Reads the file contents * Reads the file contents
*/ */
protected function ReadFile() protected function ReadFile()
{ {
$this->fileRead = true; $this->fileRead = true;
   
$fileString = file_get_contents($this->projectConfig); $fileString = file_get_contents($this->projectConfig);
if ($fileString === false) { if ($fileString === false) {
throw new GitPHP_ProjectListFileReadException($this->projectConfig); throw new GitPHP_ProjectListFileReadException($this->projectConfig);
} }
   
$this->fileContents = array(); $this->fileContents = array();
   
$fileLines = explode("\n", $fileString); $fileLines = explode("\n", $fileString);
foreach ($fileLines as $line) { foreach ($fileLines as $line) {
if (preg_match('/^([^\s]+)(\s.+)?$/', $line, $regs)) { if (preg_match('/^([^\s]+)(\s.+)?$/', $line, $regs)) {
$data = array(); $data = array();
$data['project'] = $regs[1]; $data['project'] = $regs[1];
$owner = trim($regs[2]); if (isset($regs[2])){
if (!empty($owner)) { $owner = trim($regs[2]);
$data['owner'] = $owner; if (!empty($owner)) {
  $data['owner'] = $owner;
  }
} }
$this->fileContents[] = $data; $this->fileContents[] = $data;
} }
} }
} }
   
} }
   
<?php <?php
/** /**
* Ref list load strategy using raw git objects * Ref list load strategy using raw git objects
* *
* @author Christopher Han <xiphux@gmail.com> * @author Christopher Han <xiphux@gmail.com>
* @copyright Copyright (c) 2012 Christopher Han * @copyright Copyright (c) 2012 Christopher Han
* @package GitPHP * @package GitPHP
* @subpackage Git\RefList * @subpackage Git\RefList
*/ */
abstract class GitPHP_RefListLoad_Raw abstract class GitPHP_RefListLoad_Raw
{ {
/** /**
* Loads the ref list for a ref type * Loads the ref list for a ref type
* *
* @param GitPHP_RefList $refList ref list * @param GitPHP_RefList $refList ref list
* @param string $type ref type * @param string $type ref type
* @return array array of refs * @return array array of refs
*/ */
protected function GetRefs(GitPHP_RefList $refList, $type) protected function GetRefs(GitPHP_RefList $refList, $type)
{ {
if (!$refList) if (!$refList)
return; return;
   
if (empty($type)) if (empty($type))
return; return;
   
$autotimer = new GitPHP_DebugAutoLog(); if (GitPHP_DebugLog::GetInstance()->GetEnabled())
  $autotimer = new GitPHP_DebugAutoLog();
   
$refs = array(); $refs = array();
   
$prefix = 'refs/' . $type; $prefix = 'refs/' . $type;
$fullPath = $refList->GetProject()->GetPath() . '/' . $prefix; $fullPath = $refList->GetProject()->GetPath() . '/' . $prefix;
$fullPathLen = strlen($fullPath) + 1; $fullPathLen = strlen($fullPath) + 1;
   
/* loose files */ /* loose files */
$refFiles = GitPHP_Util::ListDir($fullPath); $refFiles = GitPHP_Util::ListDir($fullPath);
for ($i = 0; $i < count($refFiles); ++$i) { for ($i = 0; $i < count($refFiles); ++$i) {
$ref = substr($refFiles[$i], $fullPathLen); $ref = substr($refFiles[$i], $fullPathLen);
   
if (empty($ref) || isset($refs[$ref])) if (empty($ref) || isset($refs[$ref]))
continue; continue;
   
$hash = trim(file_get_contents($refFiles[$i])); $hash = trim(file_get_contents($refFiles[$i]));
if (preg_match('/^[0-9A-Fa-f]{40}$/', $hash)) { if (preg_match('/^[0-9A-Fa-f]{40}$/', $hash)) {
$refs[$ref] = $hash; $refs[$ref] = $hash;
} }
} }
   
/* packed refs */ /* packed refs */
if (file_exists($refList->GetProject()->GetPath() . '/packed-refs')) { if (file_exists($refList->GetProject()->GetPath() . '/packed-refs')) {
$packedRefs = explode("\n", file_get_contents($refList->GetProject()->GetPath() . '/packed-refs')); $packedRefs = explode("\n", file_get_contents($refList->GetProject()->GetPath() . '/packed-refs'));
   
foreach ($packedRefs as $ref) { foreach ($packedRefs as $ref) {
   
if (preg_match('/^([0-9A-Fa-f]{40}) refs\/' . $type . '\/(.+)$/', $ref, $regs)) { if (preg_match('/^([0-9A-Fa-f]{40}) refs\/' . $type . '\/(.+)$/', $ref, $regs)) {
if (!isset($refs[$regs[2]])) { if (!isset($refs[$regs[2]])) {
$refs[$regs[2]] = $regs[1]; $refs[$regs[2]] = $regs[1];
} }
} }
} }
} }
   
return $refs; return $refs;
} }
} }
   
<?php <?php
/** /**
* Class representing a list of tags * Class representing a list of tags
* *
* @author Christopher Han <xiphux@gmail.com> * @author Christopher Han <xiphux@gmail.com>
* @copyright Copyright (c) 2012 Christopher Han * @copyright Copyright (c) 2012 Christopher Han
* @package GitPHP * @package GitPHP
* @subpackage Git\TagList * @subpackage Git\TagList
*/ */
class GitPHP_TagList extends GitPHP_RefList class GitPHP_TagList extends GitPHP_RefList
{ {
/** /**
* Data load strategy * Data load strategy
* *
* @var GitPHP_TagListLoadStrategy_Interface * @var GitPHP_TagListLoadStrategy_Interface
*/ */
protected $strategy; protected $strategy;
   
/** /**
* Dereferenced tag commits * Dereferenced tag commits
* *
* @var array * @var array
*/ */
protected $commits = array(); protected $commits = array();
   
/** /**
* Constructor * Constructor
* *
* @param GitPHP_Project $project project * @param GitPHP_Project $project project
* @param GitPHP_TagListLoadStrategy_Interface $strategy load strategy * @param GitPHP_TagListLoadStrategy_Interface $strategy load strategy
*/ */
public function __construct($project, GitPHP_TagListLoadStrategy_Interface $strategy) public function __construct($project, GitPHP_TagListLoadStrategy_Interface $strategy)
{ {
parent::__construct($project); parent::__construct($project);
   
if (!$strategy) if (!$strategy)
throw new Exception('Tag list load strategy is required'); throw new Exception('Tag list load strategy is required');
   
$this->SetStrategy($strategy); $this->SetStrategy($strategy);
} }
   
/** /**
* Set the load strategy * Set the load strategy
* *
* @param GitPHP_TagListLoadStrategy_Interface $strategy load strategy * @param GitPHP_TagListLoadStrategy_Interface $strategy load strategy
*/ */
public function SetStrategy(GitPHP_TagListLoadStrategy_Interface $strategy) public function SetStrategy(GitPHP_TagListLoadStrategy_Interface $strategy)
{ {
if (!$strategy) if (!$strategy)
return; return;
   
$this->strategy = $strategy; $this->strategy = $strategy;
} }
   
/** /**
* Gets the tags * Gets the tags
* *
* @return GitPHP_Tag[] array of tags * @return GitPHP_Tag[] array of tags
*/ */
public function GetTags() public function GetTags()
{ {
if (!$this->dataLoaded) if (!$this->dataLoaded)
$this->LoadData(); $this->LoadData();
   
$tags = array(); $tags = array();
   
foreach ($this->refs as $tag => $hash) { foreach ($this->refs as $tag => $hash) {
$tagObj = $this->project->GetObjectManager()->GetTag($tag, $hash); $tagObj = $this->project->GetObjectManager()->GetTag($tag, $hash);
if (isset($this->commits[$tag])) if (isset($this->commits[$tag]))
$tagObj->SetCommitHash($this->commits[$tag]); $tagObj->SetCommitHash($this->commits[$tag]);
$tags[] = $tagObj; $tags[] = $tagObj;
} }
   
return $tags; return $tags;
} }
   
/** /**
* Get tags pointing to a commit * Get tags pointing to a commit
* *
* @param GitPHP_Commit $commit commit * @param GitPHP_Commit $commit commit
* @return GitPHP_Tag[] array of tags * @return GitPHP_Tag[] array of tags
*/ */
public function GetCommitTags($commit) public function GetCommitTags($commit)
{ {
if (!$commit) if (!$commit)
return array(); return array();
   
$commitHash = $commit->GetHash(); $commitHash = $commit->GetHash();
   
if (!$this->dataLoaded) if (!$this->dataLoaded)
$this->LoadData(); $this->LoadData();
   
if (!isset($this->invertedRefs[$commitHash])) return array(); if (!isset($this->invertedRefs[$commitHash])) return array();
$tagNames = $this->invertedRefs[$commitHash]; $tagNames = $this->invertedRefs[$commitHash];
$tags = array(); $tags = array();
foreach ($tagNames as $tag) { foreach ($tagNames as $tag) {
if (isset($this->commits[$tag])) { if (isset($this->commits[$tag])) {
if ($this->commits[$tag] == $commitHash) { if ($this->commits[$tag] == $commitHash) {
$tagObj = $this->project->GetObjectManager()->GetTag($tag, $commitHash); $tagObj = $this->project->GetObjectManager()->GetTag($tag, $this->refs[$tag]);
$tagObj->SetCommitHash($this->commits[$tag]); $tagObj->SetCommitHash($this->commits[$tag]);
$tags[] = $tagObj; $tags[] = $tagObj;
} }
} else { } else {
$tagObj = $this->project->GetObjectManager()->GetTag($tag, $commitHash); $tagObj = $this->project->GetObjectManager()->GetTag($tag, $this->refs[$tag]);
$tagCommitHash = $tagObj->GetCommitHash(); $tagCommitHash = $tagObj->GetCommitHash();
if (!empty($tagCommitHash)) { if (!empty($tagCommitHash)) {
$this->commits[$tag] = $tagCommitHash; $this->commits[$tag] = $tagCommitHash;
} }
if ($tagCommitHash == $commitHash) { if ($tagCommitHash == $commitHash) {
$tags[] = $tagObj; $tags[] = $tagObj;
} }
} }
} }
return $tags; return $tags;
} }
   
/** /**
* Load tag data * Load tag data
*/ */
protected function LoadData() protected function LoadData()
{ {
$this->dataLoaded = true; $this->dataLoaded = true;
   
list($this->refs, $this->commits) = $this->strategy->Load($this); list($this->refs, $this->commits) = $this->strategy->Load($this);
foreach ($this->refs as $ref => $hash) $this->invertedRefs[$hash][] = $ref; foreach ($this->commits as $ref => $hash) $this->invertedRefs[$hash][] = $ref;
} }
   
/** /**
* Gets a tag * Gets a tag
* *
* @param string $tag tag * @param string $tag tag
* @return GitPHP_Tag tag object * @return GitPHP_Tag tag object
*/ */
public function GetTag($tag) public function GetTag($tag)
{ {
if (empty($tag)) if (empty($tag))
return null; return null;
   
if (!$this->dataLoaded) if (!$this->dataLoaded)
$this->LoadData(); $this->LoadData();
   
if (!isset($this->refs[$tag])) if (!isset($this->refs[$tag]))
return; return;
   
$tagObj = $this->project->GetObjectManager()->GetTag($tag, $this->refs[$tag]); $tagObj = $this->project->GetObjectManager()->GetTag($tag, $this->refs[$tag]);
if (isset($this->commits[$tag])) if (isset($this->commits[$tag]))
$tagObj->SetCommitHash($this->commits[$tag]); $tagObj->SetCommitHash($this->commits[$tag]);
return $tagObj; return $tagObj;
} }
   
/** /**
* Given a hash, gets the associated tag name * Given a hash, gets the associated tag name
* *
* @param string $hash hash * @param string $hash hash
* @return string tag name * @return string tag name
*/ */
public function GetTagNameFromHash($hash) public function GetTagNameFromHash($hash)
{ {
if (empty($hash)) if (empty($hash))
return null; return null;
   
if (!$this->dataLoaded) if (!$this->dataLoaded)
$this->LoadData(); $this->LoadData();
   
$tag = array_search($hash, $this->refs); $tag = array_search($hash, $this->refs);
   
if ($tag === false) if ($tag === false)
return null; return null;
   
return $tag; return $tag;
} }
   
/** /**
* Gets tags in a specific order * Gets tags in a specific order
* *
* @param string $order order to use * @param string $order order to use
* @param int $count limit the number of results * @param int $count limit the number of results
* @param int $skip skip a number of results * @param int $skip skip a number of results
* @return GitPHP_Tag[] array of tags * @return GitPHP_Tag[] array of tags
*/ */
public function GetOrderedTags($order, $count = 0, $skip = 0) public function GetOrderedTags($order, $count = 0, $skip = 0)
{ {
return $this->strategy->LoadOrdered($this, $order, $count, $skip); return $this->strategy->LoadOrdered($this, $order, $count, $skip);
} }
   
/** /**
* Returns the current revision (overrides base) * Returns the current revision (overrides base)
* *
* @return GitPHP_Tag * @return GitPHP_Tag
*/ */
function current() function current()
{ {
if (!$this->dataLoaded) { if (!$this->dataLoaded) {
$this->LoadData(); $this->LoadData();
} }
   
$tag = key($this->refs); $tag = key($this->refs);
$tagObj = $this->project->GetObjectManager()->GetTag($tag, current($this->refs)); $tagObj = $this->project->GetObjectManager()->GetTag($tag, current($this->refs));
if (isset($this->commits[$tag])) { if (isset($this->commits[$tag])) {
$tagObj->SetCommitHash($this->commits[$tag]); $tagObj->SetCommitHash($this->commits[$tag]);
} }
return $tagObj; return $tagObj;
} }
   
} }
   
<?php <?php
/** /**
* Tag list load strategy using git exe * Tag list load strategy using git exe
* *
* @author Christopher Han <xiphux@gmail.com> * @author Christopher Han <xiphux@gmail.com>
* @copyright Copyright (c) 2012 Christopher Han * @copyright Copyright (c) 2012 Christopher Han
* @package GitPHP * @package GitPHP
* @subpackage Git\TagList * @subpackage Git\TagList
*/ */
class GitPHP_TagListLoad_Git extends GitPHP_RefListLoad_Git implements GitPHP_TagListLoadStrategy_Interface class GitPHP_TagListLoad_Git extends GitPHP_RefListLoad_Git implements GitPHP_TagListLoadStrategy_Interface
{ {
/** /**
* Loads the tag list * Loads the tag list
* *
* @param GitPHP_TagList $tagList tag list * @param GitPHP_TagList $tagList tag list
* @return array array of tag hashes * @return array array of tag hashes
*/ */
public function Load($tagList) public function Load($tagList)
{ {
return $this->GetRefs($tagList, 'tags'); list($tags, $commits) = $this->GetRefs($tagList, 'tags');
   
  foreach ($tags as $tag => $tagHash) {
  if (empty($commits[$tag])) {
  // tag has no dereferenced hash - must be a light tag
  $commits[$tag] = $tagHash;
  }
  }
   
  return array($tags, $commits);
} }
   
/** /**
* Loads sorted tags * Loads sorted tags
* *
* @param GitPHP_TagList $tagList tag list * @param GitPHP_TagList $tagList tag list
* @param string $order list order * @param string $order list order
* @param integer $count number to load * @param integer $count number to load
* @param integer $skip number to skip * @param integer $skip number to skip
*/ */
public function LoadOrdered($tagList, $order, $count = 0, $skip = 0) public function LoadOrdered($tagList, $order, $count = 0, $skip = 0)
{ {
if (!$tagList) if (!$tagList)
return; return;
   
$ordered = $this->GetOrderedRefs($tagList, 'tags', $order, $count, $skip); $ordered = $this->GetOrderedRefs($tagList, 'tags', $order, $count, $skip);
   
if (!$ordered) if (!$ordered)
return; return;
   
$tagObjs = array(); $tagObjs = array();
foreach ($ordered as $tag) { foreach ($ordered as $tag) {
if ($tagList->Exists($tag)) { if ($tagList->Exists($tag)) {
$tagObjs[] = $tagList->GetTag($tag); $tagObjs[] = $tagList->GetTag($tag);
} }
} }
   
return $tagObjs; return $tagObjs;
} }
} }
   
<?php <?php
/** /**
* Tag list load strategy using raw objects * Tag list load strategy using raw objects
* *
* @author Christopher Han <xiphux@gmail.com> * @author Christopher Han <xiphux@gmail.com>
* @copyright Copyright (c) 2012 Christopher Han * @copyright Copyright (c) 2012 Christopher Han
* @package GitPHP * @package GitPHP
* @subpackage Git\TagList * @subpackage Git\TagList
*/ */
class GitPHP_TagListLoad_Raw extends GitPHP_RefListLoad_Raw implements GitPHP_TagListLoadStrategy_Interface class GitPHP_TagListLoad_Raw extends GitPHP_RefListLoad_Raw implements GitPHP_TagListLoadStrategy_Interface
{ {
/** /**
* Loads the tag list * Loads the tag list
* *
* @param GitPHP_TagList $tagList tag list * @param GitPHP_TagList $tagList tag list
* @return array array of tag hashes * @return array array of tag hashes
*/ */
public function Load($tagList) public function Load($tagList)
{ {
return array($this->GetRefs($tagList, 'tags'), array()); $tags = $this->GetRefs($tagList, 'tags');
  $commits = array();
  $objManager = $tagList->GetProject()->GetObjectManager();
  foreach ($tags as $tag => $tagHash) {
  $tagObj = $objManager->GetTag($tag, $tagHash);
  $commitHash = $tagObj->GetCommitHash();
  if (!empty($commitHash)) {
  $commits[$tag] = $commitHash;
  }
  }
  return array($tags, $commits);
} }
   
/** /**
* Loads sorted tags * Loads sorted tags
* *
* @param GitPHP_TagList $tagList tag list * @param GitPHP_TagList $tagList tag list
* @param string $order list order * @param string $order list order
* @param integer $count number to load * @param integer $count number to load
* @param integer $skip number to skip * @param integer $skip number to skip
*/ */
public function LoadOrdered($tagList, $order, $count = 0, $skip = 0) public function LoadOrdered($tagList, $order, $count = 0, $skip = 0)
{ {
if (!$tagList) if (!$tagList)
return; return;
   
if (empty($order)) if (empty($order))
return; return;
   
$tags = $tagList->GetTags(); $tags = $tagList->GetTags();
   
/* TODO add different orders */ /* TODO add different orders */
if ($order == '-creatordate') { if ($order == '-creatordate') {
@usort($tags, array('GitPHP_Tag', 'CompareCreationEpoch')); @usort($tags, array('GitPHP_Tag', 'CompareCreationEpoch'));
} }
   
if ((($count > 0) && (count($tags) > $count)) || ($skip > 0)) { if ((($count > 0) && (count($tags) > $count)) || ($skip > 0)) {
if ($count > 0) if ($count > 0)
$tags = array_slice($tags, $skip, $count); $tags = array_slice($tags, $skip, $count);
else else
$tags = array_slice($tags, $skip); $tags = array_slice($tags, $skip);
} }
   
return $tags; return $tags;
} }
} }
   
<?php <?php
/** /**
* Version header * Version header
* *
* @author Christopher Han <xiphux@gmail.com> * @author Christopher Han <xiphux@gmail.com>
* @copyright Copyright (c) 2008-2010 Christopher Han * @copyright Copyright (c) 2008-2010 Christopher Han
* @package GitPHP * @package GitPHP
*/ */
   
/** /**
* Defines the version * Defines the version
*/ */
$gitphp_version = "0.2.9"; $gitphp_version = "0.2.9.1";
   
/** /**
* Defines the app string (app name and version) * Defines the app string (app name and version)
*/ */
$gitphp_appstring = "gitphp $gitphp_version"; $gitphp_appstring = "gitphp $gitphp_version";
   
?> ?>
   
# GitPHP # GitPHP
# Copyright (C) 2010 Christopher Han # Copyright (C) 2010 Christopher Han
# This file is distributed under the same license as the GitPHP package. # This file is distributed under the same license as the GitPHP package.
# #
# Christopher Han <xiphux@gmail.com>, 2010. # Christopher Han <xiphux@gmail.com>, 2010.
# Andy Tandler <tandler@adaptik.de>, 2010. # Andy Tandler <tandler@adaptik.de>, 2010.
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: GitPHP 0.2.0\n" "Project-Id-Version: GitPHP 0.2.0\n"
"Report-Msgid-Bugs-To: xiphux@gmail.com\n" "Report-Msgid-Bugs-To: xiphux@gmail.com\n"
"POT-Creation-Date: 2010-10-02 23:01-0500\n" "POT-Creation-Date: 2010-10-02 23:01-0500\n"
"PO-Revision-Date: 2010-11-23 18:54+0100\n" "PO-Revision-Date: 2010-11-23 18:54+0100\n"
"Last-Translator: Andy Tandler <tandler@adaptik.de>\n" "Last-Translator: Andy Tandler <tandler@adaptik.de>\n"
"Language-Team: German <tandler@adaptik.de>\n" "Language-Team: German <tandler@adaptik.de>\n"
"Language: \n" "Language: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Poedit-Language: Deutsch\n" "X-Poedit-Language: Deutsch\n"
"X-Poedit-Country: Germany\n" "X-Poedit-Country: Germany\n"
"X-Poedit-SourceCharset: UTF-8\n" "X-Poedit-SourceCharset: UTF-8\n"
   
# Used as link to and title for page displaying a blob, which is what git calls a single file # Used as link to and title for page displaying a blob, which is what git calls a single file
#: templates/tree.tpl templates/blobdiff.tpl templates/commit.tpl #: templates/tree.tpl templates/blobdiff.tpl templates/commit.tpl
#: templates/searchfiles.tpl templates/history.tpl #: templates/searchfiles.tpl templates/history.tpl
#: include/controller/Controller_Blob.class.php:78 #: include/controller/Controller_Blob.class.php:78
msgid "blob" msgid "blob"
msgstr "Binärdaten" msgstr "Binärdaten"
   
# Used as link to and title for the file history, which displays all commits that have modified a certain file # Used as link to and title for the file history, which displays all commits that have modified a certain file
#: templates/tree.tpl templates/commit.tpl templates/searchfiles.tpl #: templates/tree.tpl templates/commit.tpl templates/searchfiles.tpl
#: templates/blob.tpl include/controller/Controller_History.class.php:76 #: templates/blob.tpl include/controller/Controller_History.class.php:76
msgid "history" msgid "history"
msgstr "Versionsgeschichte" msgstr "Versionsgeschichte"
   
# Used as title for and link to a list of files in a directory, which git calls a 'tree' # Used as title for and link to a list of files in a directory, which git calls a 'tree'
#: templates/tree.tpl templates/search.tpl templates/commit.tpl #: templates/tree.tpl templates/search.tpl templates/commit.tpl
#: templates/headlist.tpl templates/nav.tpl templates/searchfiles.tpl #: templates/headlist.tpl templates/nav.tpl templates/searchfiles.tpl
#: templates/log.tpl templates/projectlist.tpl templates/shortloglist.tpl #: templates/log.tpl templates/projectlist.tpl templates/shortloglist.tpl
#: include/controller/Controller_Tree.class.php:76 #: include/controller/Controller_Tree.class.php:76
msgid "tree" msgid "tree"
msgstr "Verzeichnis anzeigen" msgstr "Verzeichnis anzeigen"
   
# Used as link to download a copy of the files in a given commit # Used as link to download a copy of the files in a given commit
#: templates/tree.tpl templates/search.tpl templates/commit.tpl #: templates/tree.tpl templates/search.tpl templates/commit.tpl
#: templates/taglist.tpl templates/projectlist.tpl templates/shortloglist.tpl #: templates/taglist.tpl templates/projectlist.tpl templates/shortloglist.tpl
#: include/controller/Controller_Snapshot.class.php:76 #: include/controller/Controller_Snapshot.class.php:76
msgid "snapshot" msgid "snapshot"
msgstr "Abbild erzeugen" msgstr "Abbild erzeugen"
   
# Used to label something stored in a git repository where the type of item - tag, blob, etc - isn't known # Used to label something stored in a git repository where the type of item - tag, blob, etc - isn't known
#: templates/tag.tpl #: templates/tag.tpl
msgid "object" msgid "object"
msgstr "Objekt" msgstr "Objekt"
   
# Used as link to and title for page displaying info about a single commit in the project # Used as link to and title for page displaying info about a single commit in the project
#: templates/tag.tpl templates/search.tpl templates/commit.tpl #: templates/tag.tpl templates/search.tpl templates/commit.tpl
#: templates/nav.tpl templates/taglist.tpl templates/header.tpl #: templates/nav.tpl templates/taglist.tpl templates/header.tpl
#: templates/log.tpl templates/history.tpl templates/shortloglist.tpl #: templates/log.tpl templates/history.tpl templates/shortloglist.tpl
#: include/controller/Controller_Commit.class.php:79 #: include/controller/Controller_Commit.class.php:79
msgid "commit" msgid "commit"
msgstr "Änderungen" msgstr "Änderungen"
   
# Used as link to and title for page displaying detailed info about a tag # Used as link to and title for page displaying detailed info about a tag
#: templates/tag.tpl templates/tagtip.tpl templates/taglist.tpl #: templates/tag.tpl templates/tagtip.tpl templates/taglist.tpl
#: include/controller/Controller_Tag.class.php:79 #: include/controller/Controller_Tag.class.php:79
msgid "tag" msgid "tag"
msgstr "Versionsstand" msgstr "Versionsstand"
   
# Used to label the author of the commit, and as a field to search # Used to label the author of the commit, and as a field to search
# The author is the person who wrote the changes in the commit # The author is the person who wrote the changes in the commit
#: templates/tag.tpl templates/commit.tpl templates/committip.tpl #: templates/tag.tpl templates/commit.tpl templates/committip.tpl
#: templates/header.tpl #: templates/header.tpl
msgid "author" msgid "author"
msgstr "Autor" msgstr "Autor"
   
# Used as a link to a plaintext version of a page # Used as a link to a plaintext version of a page
#: templates/tree.tpl templates/blobdiff.tpl templates/blame.tpl #: templates/tree.tpl templates/blobdiff.tpl templates/blame.tpl
#: templates/commitdiff.tpl templates/blob.tpl #: templates/commitdiff.tpl templates/blob.tpl
msgid "plain" msgid "plain"
msgstr "Rohdaten" msgstr "Rohdaten"
   
# Used as a link to the first page in a list of results # Used as a link to the first page in a list of results
#: templates/search.tpl templates/searchfiles.tpl #: templates/search.tpl templates/searchfiles.tpl
msgid "first" msgid "first"
msgstr "erstes" msgstr "erstes"
   
# Used as a link to the previous page in a list of results # Used as a link to the previous page in a list of results
#: templates/search.tpl templates/searchfiles.tpl templates/log.tpl #: templates/search.tpl templates/searchfiles.tpl templates/log.tpl
#: templates/shortlog.tpl #: templates/shortlog.tpl
msgid "prev" msgid "prev"
msgstr "Vorherige" msgstr "Vorherige"
   
# Used as a link to the next page in a list of results # Used as a link to the next page in a list of results
#: templates/search.tpl templates/searchfiles.tpl templates/log.tpl #: templates/search.tpl templates/searchfiles.tpl templates/log.tpl
#: templates/shortlog.tpl templates/shortloglist.tpl #: templates/shortlog.tpl templates/shortloglist.tpl
msgid "next" msgid "next"
msgstr "Nächste" msgstr "Nächste"
   
# Used as link to and title for the full diff of all the changes in a commit # Used as link to and title for the full diff of all the changes in a commit
#: templates/search.tpl templates/commit.tpl templates/nav.tpl #: templates/search.tpl templates/commit.tpl templates/nav.tpl
#: templates/log.tpl templates/history.tpl templates/shortloglist.tpl #: templates/log.tpl templates/history.tpl templates/shortloglist.tpl
#: include/controller/Controller_Commitdiff.class.php:79 #: include/controller/Controller_Commitdiff.class.php:79
msgid "commitdiff" msgid "commitdiff"
msgstr "Vergleichen" msgstr "Vergleichen"
   
# Used to label the committer of the commit, and as a field to search # Used to label the committer of the commit, and as a field to search
# The committer is the person who put the commit into this project # The committer is the person who put the commit into this project
#: templates/commit.tpl templates/committip.tpl templates/header.tpl #: templates/commit.tpl templates/committip.tpl templates/header.tpl
msgid "committer" msgid "committer"
msgstr "Eintragender" msgstr "Eintragender"
   
# Used to label the parent of this commit # Used to label the parent of this commit
# The parent is the commit preceding this one in the project history # The parent is the commit preceding this one in the project history
#: templates/commit.tpl #: templates/commit.tpl
msgid "parent" msgid "parent"
msgstr "Eltern" msgstr "Eltern"
   
# Used to indicate the number of files changed in a commit # Used to indicate the number of files changed in a commit
# Comes before a list of files # Comes before a list of files
# %1: the number of files # %1: the number of files
#: templates/commit.tpl #: templates/commit.tpl
msgid "%1 file changed:" msgid "%1 file changed:"
msgid_plural "%1 files changed:" msgid_plural "%1 files changed:"
msgstr[0] "%1 datei geändert:" msgstr[0] "%1 datei geändert:"
msgstr[1] "%1 dateien geändert:" msgstr[1] "%1 dateien geändert:"
   
# Used to indicate a new object was added with an access mode # Used to indicate a new object was added with an access mode
# %1: the type of object # %1: the type of object
# %2: the mode # %2: the mode
#: templates/commit.tpl #: templates/commit.tpl
msgid "new %1 with mode %2" msgid "new %1 with mode %2"
msgstr "" msgstr "Neu %1 mit Modus %2"
   
# Used to indicate a new object was added # Used to indicate a new object was added
# %1: the type of object # %1: the type of object
#: templates/commit.tpl #: templates/commit.tpl
msgid "new %1" msgid "new %1"
msgstr "%1 neu" msgstr "%1 neu"
   
# Used to indicate an object was deleted # Used to indicate an object was deleted
# %1: the type of object # %1: the type of object
#: templates/commit.tpl #: templates/commit.tpl
msgid "deleted %1" msgid "deleted %1"
msgstr "%1 gelöscht" msgstr "%1 gelöscht"
   
# Used to indicate a file type changed, including original and new file modes # Used to indicate a file type changed, including original and new file modes
# (when both original and new files are regular files) # (when both original and new files are regular files)
# %1: the original file type # %1: the original file type
# %2: the new file type # %2: the new file type
# %3: the original file mode # %3: the original file mode
# %4: the new file mode # %4: the new file mode
#: templates/commit.tpl #: templates/commit.tpl
msgid "changed from %1 to %2 mode: %3 -> %4" msgid "changed from %1 to %2 mode: %3 -> %4"
msgstr "" msgstr "geändert von %1 zu %2 Modus: %3 -> %4"
   
# Used to indicate a file type changed, with only new file mode # Used to indicate a file type changed, with only new file mode
# (when old file type wasn't a normal file) # (when old file type wasn't a normal file)
# %1: the original file type # %1: the original file type
# %2: the new file type # %2: the new file type
# %3: the original file mode # %3: the original file mode
# %4: the new file mode # %4: the new file mode
#: templates/commit.tpl #: templates/commit.tpl
msgid "changed from %1 to %2 mode: %3" msgid "changed from %1 to %2 mode: %3"
msgstr "" msgstr "geändert von %1 zu %2 Modus %3"
   
# Used to indicate a file type changed # Used to indicate a file type changed
# %1: the original file type # %1: the original file type
# %2: the new file type # %2: the new file type
#: templates/commit.tpl #: templates/commit.tpl
msgid "changed from %1 to %2" msgid "changed from %1 to %2"
msgstr "" msgstr "geändert von %1 zu %2"
   
# Used to indicate a file mode changed # Used to indicate a file mode changed
# %1: the original file mode # %1: the original file mode
# %2: the new file mode # %2: the new file mode
#: templates/commit.tpl #: templates/commit.tpl
msgid "changed mode: %1 -> %2" msgid "changed mode: %1 -> %2"
msgstr "" msgstr "geänderter Modus: %1 -> %2"
   
# Used to indicate a file mode changed # Used to indicate a file mode changed
# %1: the new file mode # %1: the new file mode
#: templates/commit.tpl #: templates/commit.tpl
msgid "changed mode: %1" msgid "changed mode: %1"
msgstr "" msgstr "geänderter Modus: %1"
   
# Used to indicate a file mode changed # Used to indicate a file mode changed
#: templates/commit.tpl #: templates/commit.tpl
msgid "changed" msgid "changed"
msgstr "geändert" msgstr "geändert"
   
# Used as link to diff this file version with the previous version # Used as link to diff this file version with the previous version
#: templates/commit.tpl #: templates/commit.tpl
msgid "diff" msgid "diff"
msgstr "Unterschied" msgstr "Unterschied"
   
# Used to indicate a file was moved and the file mode changed # Used to indicate a file was moved and the file mode changed
# This string should be HTML safe # This string should be HTML safe
# %1: the old file # %1: the old file
# %2: the similarity as a percent number # %2: the similarity as a percent number
# %3: the new file mode # %3: the new file mode
#: templates/commit.tpl #: templates/commit.tpl
msgid "moved from %1 with %2%% similarity, mode: %3" msgid "moved from %1 with %2%% similarity, mode: %3"
msgstr "" msgstr "verschoben von %1 mit %2%% der selbe Modus: %3"
   
# Used to indicate a file was moved # Used to indicate a file was moved
# This string should be HTML safe # This string should be HTML safe
# %1: the old file # %1: the old file
# %2: the similarity as a percent number # %2: the similarity as a percent number
#: templates/commit.tpl #: templates/commit.tpl
msgid "moved from %1 with %2%% similarity" msgid "moved from %1 with %2%% similarity"
msgstr "" msgstr "verschoben von %1 mit %2%% das selbe"
   
# Used as title for and link to the compact log view with one line abbreviated commits # Used as title for and link to the compact log view with one line abbreviated commits
#: templates/headlist.tpl templates/nav.tpl templates/taglist.tpl #: templates/headlist.tpl templates/nav.tpl templates/taglist.tpl
#: templates/title.tpl templates/projectlist.tpl #: templates/title.tpl templates/projectlist.tpl
#: include/controller/Controller_Log.class.php:80 #: include/controller/Controller_Log.class.php:80
msgid "shortlog" msgid "shortlog"
msgstr "Kurzfassung" msgstr "Kurzfassung"
   
# Used as title for and link to log view with full commit messages # Used as title for and link to log view with full commit messages
#: templates/headlist.tpl templates/nav.tpl templates/taglist.tpl #: templates/headlist.tpl templates/nav.tpl templates/taglist.tpl
#: templates/projectlist.tpl include/controller/Controller_Log.class.php:85 #: templates/projectlist.tpl include/controller/Controller_Log.class.php:85
msgid "log" msgid "log"
msgstr "Journal" msgstr "Journal"
   
# Used as title for and link to project summary page # Used as title for and link to project summary page
#: templates/nav.tpl templates/projectlist.tpl #: templates/nav.tpl templates/projectlist.tpl
#: include/controller/Controller_Project.class.php:75 #: include/controller/Controller_Project.class.php:75
msgid "summary" msgid "summary"
msgstr "Zusammenfassung" msgstr "Zusammenfassung"
   
# Link back to the list of projects # Link back to the list of projects
#: templates/header.tpl include/controller/ControllerBase.class.php:240 #: templates/header.tpl include/controller/ControllerBase.class.php:240
#: include/controller/Controller_ProjectList.class.php:94 #: include/controller/Controller_ProjectList.class.php:94
msgid "projects" msgid "projects"
msgstr "Projekte" msgstr "Projekte"
   
# Used as a search type, to search the contents of files in the project # Used as a search type, to search the contents of files in the project
#: templates/header.tpl include/git/Blob.class.php:191 #: templates/header.tpl include/git/Blob.class.php:191
msgid "file" msgid "file"
msgstr "Datei" msgstr "Datei"
   
# Used as title for search page, and also is the label for the search box # Used as title for search page, and also is the label for the search box
#: templates/header.tpl include/controller/Controller_Search.class.php:90 #: templates/header.tpl include/controller/Controller_Search.class.php:90
msgid "search" msgid "search"
msgstr "Suche" msgstr "Suche"
   
# Used as a link to the HEAD of a project for a log or file # Used as a link to the HEAD of a project for a log or file
# (note: HEAD is standard git terminology) # (note: HEAD is standard git terminology)
#: templates/blame.tpl templates/log.tpl templates/shortlog.tpl #: templates/blame.tpl templates/log.tpl templates/shortlog.tpl
#: templates/blob.tpl #: templates/blob.tpl
msgid "HEAD" msgid "HEAD"
msgstr "HEAD" msgstr "HEAD"
   
# Used to indicate the last change in a project # Used to indicate the last change in a project
# %1: the timestamp of the latest change # %1: the timestamp of the latest change
#: templates/log.tpl #: templates/log.tpl
msgid "Last change %1" msgid "Last change %1"
msgstr "Letzte Änderungen %1" msgstr "Letzte Änderungen %1"
   
# Message displayed when there are no commits in the project to display # Message displayed when there are no commits in the project to display
#: templates/log.tpl templates/shortloglist.tpl #: templates/log.tpl templates/shortloglist.tpl
msgid "No commits" msgid "No commits"
msgstr "Keine Änderungen" msgstr "Keine Änderungen"
   
# Used as link to diff this file version with the current file # Used as link to diff this file version with the current file
#: templates/history.tpl #: templates/history.tpl
msgid "diff to current" msgid "diff to current"
msgstr "Unterschied zur aktuellen Version" msgstr "Unterschied zur aktuellen Version"
   
# Used as link to and title for page showing all tags in a project # Used as link to and title for page showing all tags in a project
#: templates/title.tpl include/controller/Controller_Tags.class.php:76 #: templates/title.tpl include/controller/Controller_Tags.class.php:76
msgid "tags" msgid "tags"
msgstr "Versionsstände" msgstr "Versionsstände"
   
# Used as link to and title for page showing all heads in a project # Used as link to and title for page showing all heads in a project
#: templates/title.tpl include/controller/Controller_Heads.class.php:76 #: templates/title.tpl include/controller/Controller_Heads.class.php:76
msgid "heads" msgid "heads"
msgstr "" msgstr "Heads"
   
# Used when diffing a file, to indicate that it's been deleted # Used when diffing a file, to indicate that it's been deleted
#: templates/commitdiff.tpl #: templates/commitdiff.tpl
msgid "(deleted)" msgid "(deleted)"
msgstr "(gelöscht)" msgstr "(gelöscht)"
   
# Used when diffing a file, to indicate that it's a new file # Used when diffing a file, to indicate that it's a new file
#: templates/commitdiff.tpl #: templates/commitdiff.tpl
msgid "(new)" msgid "(new)"
msgstr "(neu)" msgstr "(neu)"
   
# Used to label the project description # Used to label the project description
#: templates/project.tpl #: templates/project.tpl
msgid "description" msgid "description"
msgstr "Beschreibung" msgstr "Beschreibung"
   
# Used to label the project owner # Used to label the project owner
#: templates/project.tpl #: templates/project.tpl
msgid "owner" msgid "owner"
msgstr "Urheber" msgstr "Urheber"
   
# Used to label the time the project was last changed # Used to label the time the project was last changed
# (the time of the most recent commit) # (the time of the most recent commit)
#: templates/project.tpl #: templates/project.tpl
msgid "last change" msgid "last change"
msgstr "Letzte Änderung" msgstr "Letzte Änderung"
   
# Used to label the url that users can use to clone the project # Used to label the url that users can use to clone the project
#: templates/project.tpl #: templates/project.tpl
msgid "clone url" msgid "clone url"
msgstr "Klone URL (clone)" msgstr "Clone URL"
   
# Used to label the url that users can use to push commits to the project # Used to label the url that users can use to push commits to the project
#: templates/project.tpl #: templates/project.tpl
msgid "push url" msgid "push url"
msgstr "Patch URL (push)" msgstr "Push URL"
   
# Used as the header for the project name column # Used as the header for the project name column
#: templates/projectlist.tpl #: templates/projectlist.tpl
msgid "Project" msgid "Project"
msgstr "Projekt" msgstr "Projekt"
   
# Used as the header for the project description column # Used as the header for the project description column
#: templates/projectlist.tpl #: templates/projectlist.tpl
msgid "Description" msgid "Description"
msgstr "Beschreibung" msgstr "Beschreibung"
   
# Used as the header for the column showing the person that owns the project # Used as the header for the column showing the person that owns the project
#: templates/projectlist.tpl #: templates/projectlist.tpl
msgid "Owner" msgid "Owner"
msgstr "Urheber" msgstr "Urheber"
   
# Used as the header for the last change column # Used as the header for the last change column
# (how long ago was the last commit) # (how long ago was the last commit)
#: templates/projectlist.tpl #: templates/projectlist.tpl
msgid "Last Change" msgid "Last Change"
msgstr "Alter" msgstr "Alter"
   
# Used as the header for the actions column, which is a list of links users can use to jump to various parts of this project # Used as the header for the actions column, which is a list of links users can use to jump to various parts of this project
#: templates/projectlist.tpl #: templates/projectlist.tpl
msgid "Actions" msgid "Actions"
msgstr "Funktionen" msgstr "Funktionen"
   
# Message shown when there were no projects found to display # Message shown when there were no projects found to display
#: templates/projectlist.tpl #: templates/projectlist.tpl
msgid "No projects found" msgid "No projects found"
msgstr "Keine Projekte gefunden" msgstr "Keine Projekte gefunden"
   
# Used as link to and title for page displaying blame info (who last touched what line) in a file # Used as link to and title for page displaying blame info (who last touched what line) in a file
#: templates/blob.tpl include/controller/Controller_Blame.class.php:79 #: templates/blob.tpl include/controller/Controller_Blame.class.php:79
msgid "blame" msgid "blame"
msgstr "Kommentare" msgstr "Kommentare"
   
# Error message when user tries to do an action that requires a project but a project isn't specified # Error message when user tries to do an action that requires a project but a project isn't specified
#: include/controller/Controller_Rss.class.php:35 #: include/controller/Controller_Rss.class.php:35
#: include/controller/Controller_Tree.class.php:34 #: include/controller/Controller_Tree.class.php:34
#: include/controller/Controller_Commit.class.php:34 #: include/controller/Controller_Commit.class.php:34
#: include/controller/Controller_Log.class.php:34 #: include/controller/Controller_Log.class.php:34
#: include/controller/Controller_Blame.class.php:34 #: include/controller/Controller_Blame.class.php:34
#: include/controller/Controller_Snapshot.class.php:34 #: include/controller/Controller_Snapshot.class.php:34
#: include/controller/Controller_Blob.class.php:34 #: include/controller/Controller_Blob.class.php:34
#: include/controller/Controller_Tag.class.php:34 #: include/controller/Controller_Tag.class.php:34
#: include/controller/Controller_Tags.class.php:34 #: include/controller/Controller_Tags.class.php:34
#: include/controller/Controller_Project.class.php:33 #: include/controller/Controller_Project.class.php:33
#: include/controller/Controller_Commitdiff.class.php:34 #: include/controller/Controller_Commitdiff.class.php:34
#: include/controller/Controller_Blobdiff.class.php:34 #: include/controller/Controller_Blobdiff.class.php:34
#: include/controller/Controller_History.class.php:34 #: include/controller/Controller_History.class.php:34
#: include/controller/Controller_Heads.class.php:34 #: include/controller/Controller_Heads.class.php:34
#: include/controller/Controller_Search.class.php:44 #: include/controller/Controller_Search.class.php:44
msgid "Project is required" msgid "Project is required"
msgstr "Projekt wird benötigt" msgstr "Projekt wird benötigt"
   
# Used as the title of the rss controller # Used as the title of the rss controller
# rss is a standard web feed format # rss is a standard web feed format
#: include/controller/Controller_Rss.class.php:77 #: include/controller/Controller_Rss.class.php:77
msgid "rss" msgid "rss"
msgstr "RSS" msgstr "RSS"
   
# Used as link to and title for a diff of a single file # Used as link to and title for a diff of a single file
#: include/controller/Controller_Blobdiff.class.php:79 #: include/controller/Controller_Blobdiff.class.php:79
msgid "blobdiff" msgid "blobdiff"
msgstr "Unterschied binär" msgstr "Unterschied binär"
   
# Error message when user tries to access a project that doesn't exist # Error message when user tries to access a project that doesn't exist
# %1$s: the project the user tried to access # %1$s: the project the user tried to access
#: include/controller/ControllerBase.class.php:84 #: include/controller/ControllerBase.class.php:84
#, php-format #, php-format
msgid "Invalid project %1$s" msgid "Invalid project %1$s"
msgstr "Projekt %1$s ungültig" msgstr "Projekt %1$s ungültig"
   
# Used as the title for the opml controller # Used as the title for the opml controller
# OPML is a standard XML outline format # OPML is a standard XML outline format
#: include/controller/Controller_ProjectList.class.php:84 #: include/controller/Controller_ProjectList.class.php:84
msgid "opml" msgid "opml"
msgstr "OPML" msgstr "OPML"
   
# Used as the title of the project index controller # Used as the title of the project index controller
#: include/controller/Controller_ProjectList.class.php:89 #: include/controller/Controller_ProjectList.class.php:89
msgid "project index" msgid "project index"
msgstr "Projekt Index" msgstr "Projekt Index"
   
# Error message when a user tries to search but searching has been disabled in the config # Error message when a user tries to search but searching has been disabled in the config
#: include/controller/Controller_Search.class.php:38 #: include/controller/Controller_Search.class.php:38
msgid "Search has been disabled" msgid "Search has been disabled"
msgstr "Suche wurde deaktiviert" msgstr "Suche wurde deaktiviert"
   
# Error message when a user tries to do a file search but searching files has been disabled in the config # Error message when a user tries to do a file search but searching files has been disabled in the config
#: include/controller/Controller_Search.class.php:109 #: include/controller/Controller_Search.class.php:109
msgid "File search has been disabled" msgid "File search has been disabled"
msgstr "Dateisuche wurde deaktiviert" msgstr "Dateisuche wurde deaktiviert"
   
# Error message when a user's search query is too short # Error message when a user's search query is too short
# %1$d: the minimum number of characters # %1$d: the minimum number of characters
#: include/controller/Controller_Search.class.php:115 #: include/controller/Controller_Search.class.php:115
#, php-format #, php-format
msgid "You must enter search text of at least %1$d character" msgid "You must enter search text of at least %1$d character"
msgid_plural "You must enter search text of at least %1$d characters" msgid_plural "You must enter search text of at least %1$d characters"
msgstr[0] "Der Suchbegriff muss mindestens %1$d Zeichen beinhalten" msgstr[0] "Der Suchbegriff muss mindestens %1$d Zeichen beinhalten"
msgstr[1] "Der Suchbegriff muss mindestens %1$d Zeichen beinhalten" msgstr[1] "Der Suchbegriff muss mindestens %1$d Zeichen beinhalten"
   
# Error message when the user enters an unsupported search type # Error message when the user enters an unsupported search type
#: include/controller/Controller_Search.class.php:159 #: include/controller/Controller_Search.class.php:159
msgid "Invalid search type" msgid "Invalid search type"
msgstr "Ungültiger Suchparameter" msgstr "Ungültiger Suchparameter"
   
# Error message when a user's search didn't produce any results # Error message when a user's search didn't produce any results
# %1$s: the user's search string # %1$s: the user's search string
#: include/controller/Controller_Search.class.php:165 #: include/controller/Controller_Search.class.php:165
#, php-format #, php-format
msgid "No matches for \"%1\"" msgid "No matches for \"%1\""
msgstr "Keine Ergebnisse für \"%1\"" msgstr "Keine Ergebnisse für \"%1\""
   
# A type of filesystem object stored in a project # A type of filesystem object stored in a project
#: include/git/Blob.class.php:179 #: include/git/Blob.class.php:179
msgid "directory" msgid "directory"
msgstr "Verzeichnis" msgstr "Verzeichnis"
   
# A type of filesystem object stored in a project # A type of filesystem object stored in a project
#: include/git/Blob.class.php:185 #: include/git/Blob.class.php:185
msgid "symlink" msgid "symlink"
msgstr "symlink" msgstr "Symlink"
   
# Used when an object is stored in a project but git doesn't know what type it is # Used when an object is stored in a project but git doesn't know what type it is
#: include/git/Blob.class.php:198 #: include/git/Blob.class.php:198
msgid "unknown" msgid "unknown"
msgstr "unbekannt" msgstr "unbekannt"
   
# Error message when user specifies a path for a project root or project, but the path given isn't a directory # Error message when user specifies a path for a project root or project, but the path given isn't a directory
# %1$s: the path the user specified # %1$s: the path the user specified
#: include/git/ProjectListDirectory.class.php:47 #: include/git/ProjectListDirectory.class.php:47
#: include/git/Project.class.php:212 #: include/git/Project.class.php:212
#, php-format #, php-format
msgid "%1$s is not a directory" msgid "%1$s is not a directory"
msgstr "%1$s ist kein Verzeichnis" msgstr "%1$s ist kein Verzeichnis"
   
# Error message when a path specified in the config is not a git repository # Error message when a path specified in the config is not a git repository
# %1$s: the specified path # %1$s: the specified path
#: include/git/Project.class.php:216 #: include/git/Project.class.php:216
#, php-format #, php-format
msgid "%1$s is not a git repository" msgid "%1$s is not a git repository"
msgstr "%1$s ist kein git repository" msgstr "%1$s ist kein git repository"
   
# Error message when a path specified is using '..' to break out of the project root (a hack attempt) # Error message when a path specified is using '..' to break out of the project root (a hack attempt)
# %1$s: The specified path # %1$s: The specified path
#: include/git/Project.class.php:220 #: include/git/Project.class.php:220
#, php-format #, php-format
msgid "%1$s is attempting directory traversal" msgid "%1$s is attempting directory traversal"
msgstr "" msgstr "%1$s versucht eine Pfad Manipulation "
   
# Error message when a path specified is outside of the project root # Error message when a path specified is outside of the project root
# %1$s: The specified path # %1$s: The specified path
#: include/git/Project.class.php:226 #: include/git/Project.class.php:226
#, php-format #, php-format
msgid "%1$s is outside of the projectroot" msgid "%1$s is outside of the projectroot"
msgstr "%1$s liegt ausserhalb des Projektverzeichnisses" msgstr "%1$s liegt ausserhalb des Projektverzeichnisses"
   
# Error message when user tries to specify a file with a list of the projects, but it isn't a file # Error message when user tries to specify a file with a list of the projects, but it isn't a file
# %1$s: the path the user specified # %1$s: the path the user specified
#: include/git/ProjectListFile.class.php:38 #: include/git/ProjectListFile.class.php:38
#, php-format #, php-format
msgid "%1$s is not a file" msgid "%1$s is not a file"
msgstr "%1$s ist keine Datei" msgstr "%1$s ist keine Datei"
   
# Error message when user tries to specify a file with a list of the projects, but the system can't read the file # Error message when user tries to specify a file with a list of the projects, but the system can't read the file
# %1$s: the file the user specified # %1$s: the file the user specified
#: include/git/ProjectListFile.class.php:57 #: include/git/ProjectListFile.class.php:57
#, php-format #, php-format
msgid "Failed to open project list file %1$s" msgid "Failed to open project list file %1$s"
msgstr "Datei %1$s mit der Projektliste kann nicht geöffnet werden" msgstr "Datei %1$s mit der Projektliste kann nicht geöffnet werden"
   
# Error message when a hash specified in a URL isn't a valid git hash # Error message when a hash specified in a URL isn't a valid git hash
# %1$s: the hash entered # %1$s: the hash entered
#: include/git/GitObject.class.php:95 #: include/git/GitObject.class.php:95
#, php-format #, php-format
msgid "Invalid hash %1$s" msgid "Invalid hash %1$s"
msgstr "Ungültiger Hash-Wert %1$s" msgstr "Ungültiger Hash-Wert %1$s"
   
# Used to represent an age in years # Used to represent an age in years
# %1$d: the number of years # %1$d: the number of years
#: include/smartyplugins/modifier.agestring.php:17 #: include/smartyplugins/modifier.agestring.php:17
#, php-format #, php-format
msgid "%1$d year ago" msgid "%1$d year ago"
msgid_plural "%1$d years ago" msgid_plural "%1$d years ago"
msgstr[0] "%1$d Jahr alt" msgstr[0] "%1$d Jahr alt"
msgstr[1] "%1$d Jahre alt" msgstr[1] "%1$d Jahre alt"
   
# Used to represent an age in months # Used to represent an age in months
# %1$d: the number of months # %1$d: the number of months
#: include/smartyplugins/modifier.agestring.php:22 #: include/smartyplugins/modifier.agestring.php:22
#, php-format #, php-format
msgid "%1$d month ago" msgid "%1$d month ago"
msgid_plural "%1$d months ago" msgid_plural "%1$d months ago"
msgstr[0] "%1$d Monat alt" msgstr[0] "%1$d Monat alt"
msgstr[1] "%1$d Monate alt" msgstr[1] "%1$d Monate alt"
   
# Used to represent an age in weeks # Used to represent an age in weeks
# %1$d: the number of weeks # %1$d: the number of weeks
#: include/smartyplugins/modifier.agestring.php:27 #: include/smartyplugins/modifier.agestring.php:27
#, php-format #, php-format
msgid "%1$d week ago" msgid "%1$d week ago"
msgid_plural "%1$d weeks ago" msgid_plural "%1$d weeks ago"
msgstr[0] "%1$d Woche alt" msgstr[0] "%1$d Woche alt"
msgstr[1] "%1$d Wochen alt" msgstr[1] "%1$d Wochen alt"
   
# Used to represent an age in days # Used to represent an age in days
# %1$d: the number of days # %1$d: the number of days
#: include/smartyplugins/modifier.agestring.php:32 #: include/smartyplugins/modifier.agestring.php:32
#, php-format #, php-format
msgid "%1$d day ago" msgid "%1$d day ago"
msgid_plural "%1$d days ago" msgid_plural "%1$d days ago"
msgstr[0] "%1$d Tag alt" msgstr[0] "%1$d Tag alt"
msgstr[1] "%1$d Tage alt" msgstr[1] "%1$d Tage alt"
   
# Used to represent an age in hours # Used to represent an age in hours
# %1$d: the number of hours # %1$d: the number of hours
#: include/smartyplugins/modifier.agestring.php:37 #: include/smartyplugins/modifier.agestring.php:37
#, php-format #, php-format
msgid "%1$d hour ago" msgid "%1$d hour ago"
msgid_plural "%1$d hours ago" msgid_plural "%1$d hours ago"
msgstr[0] "%1$d Stunde alt" msgstr[0] "%1$d Stunde alt"
msgstr[1] "%1$d Stunden alt" msgstr[1] "%1$d Stunden alt"
   
# Used to represent an age in minutes # Used to represent an age in minutes
# %1$d: the number of minutes # %1$d: the number of minutes
#: include/smartyplugins/modifier.agestring.php:42 #: include/smartyplugins/modifier.agestring.php:42
#, php-format #, php-format
msgid "%1$d min ago" msgid "%1$d min ago"
msgid_plural "%1$d min ago" msgid_plural "%1$d min ago"
msgstr[0] "%1$d Minute alt" msgstr[0] "%1$d Minute alt"
msgstr[1] "%1$d Minuten alt" msgstr[1] "%1$d Minuten alt"
   
# Used to represent an age in seconds # Used to represent an age in seconds
# %1$d: the number of seconds # %1$d: the number of seconds
#: include/smartyplugins/modifier.agestring.php:47 #: include/smartyplugins/modifier.agestring.php:47
#, php-format #, php-format
msgid "%1$d sec ago" msgid "%1$d sec ago"
msgid_plural "%1$d sec ago" msgid_plural "%1$d sec ago"
msgstr[0] "%1$d Sekunde alt" msgstr[0] "%1$d Sekunde alt"
msgstr[1] "%1$d Sekunden alt" msgstr[1] "%1$d Sekunden alt"
   
# Used to represent a modification time of right now # Used to represent a modification time of right now
#: include/smartyplugins/modifier.agestring.php:51 #: include/smartyplugins/modifier.agestring.php:51
msgid "right now" msgid "right now"
msgstr "" msgstr "gerade eben"
   
# Error message when user hasn't defined a project root in the config # Error message when user hasn't defined a project root in the config
# "projectroot" refers to a root directory where the user's git projects are stored # "projectroot" refers to a root directory where the user's git projects are stored
#: index.php:113 #: index.php:113
msgid "A projectroot must be set in the config" msgid "A projectroot must be set in the config"
msgstr "Der Projektpfad muss in die Konfiguration eingetragen werden" msgstr "Der Projektpfad muss in die Konfiguration eingetragen werden"
   
# Caption for the rss button for a project # Caption for the rss button for a project
# rss is a standard web feed format # rss is a standard web feed format
#: templates/footer.tpl #: templates/footer.tpl
msgid "RSS" msgid "RSS"
msgstr "RSS" msgstr "RSS"
   
# Caption for the OPML button on the project list # Caption for the OPML button on the project list
# OPML is a standard XML outline format # OPML is a standard XML outline format
#: templates/footer.tpl #: templates/footer.tpl
msgid "OPML" msgid "OPML"
msgstr "OPML" msgstr "OPML"
   
# Caption for the button to get a plaintext list of projects # Caption for the button to get a plaintext list of projects
#: templates/footer.tpl #: templates/footer.tpl
msgid "TXT" msgid "TXT"
msgstr "TXT" msgstr "TXT"
   
# Label for the selected commit, when selecting commits to diff # Label for the selected commit, when selecting commits to diff
#: templates/log.tpl templates/shortlog.tpl #: templates/log.tpl templates/shortlog.tpl
msgid "selected" msgid "selected"
msgstr "Zum Vergleich" msgstr "Zum Vergleich"
   
# Link to deselect the currently selected diff # Link to deselect the currently selected diff
#: templates/log.tpl templates/shortlog.tpl templates/shortloglist.tpl #: templates/log.tpl templates/shortlog.tpl templates/shortloglist.tpl
msgid "deselect" msgid "deselect"
msgstr "Nicht vergleichen" msgstr "Nicht vergleichen"
   
# Link beside commits - diffs this commit against the currently selected commit # Link beside commits - diffs this commit against the currently selected commit
#: templates/log.tpl templates/shortloglist.tpl #: templates/log.tpl templates/shortloglist.tpl
msgid "diff with selected" msgid "diff with selected"
msgstr "Mit Auswahl vergleichen" msgstr "Mit Auswahl vergleichen"
   
# Link beside commits - selects this commit to be used in a diff # Link beside commits - selects this commit to be used in a diff
#: templates/log.tpl templates/shortloglist.tpl #: templates/log.tpl templates/shortloglist.tpl
msgid "select for diff" msgid "select for diff"
msgstr "Zum Vergleich auswählen" msgstr "Zum Vergleich auswählen"
   
# Used as an alternate text on javascript "loading" images # Used as an alternate text on javascript "loading" images
#: templates/header.tpl #: templates/header.tpl
msgid "Loading…" msgid "Loading…"
msgstr "Lädt..." msgstr "Lädt..."
   
# Used as a loading message while blame data is being pulled from the server # Used as a loading message while blame data is being pulled from the server
#: templates/header.tpl #: templates/header.tpl
msgid "Loading blame data…" msgid "Loading blame data…"
msgstr "Lade Kommentare..." msgstr "Lade Kommentare..."
   
# Used as a label by the language selector drop-down box # Used as a label by the language selector drop-down box
#: templates/header.tpl #: templates/header.tpl
msgid "language:" msgid "language:"
msgstr "Sprache:" msgstr "Sprache:"
   
# Used as a button by the language selector drop-down box to set the # Used as a button by the language selector drop-down box to set the
# language to the user's choice # language to the user's choice
#: templates/header.tpl #: templates/header.tpl
msgid "set" msgid "set"
msgstr "" msgstr "einstellen"
   
# Caption for the Atom button for a project # Caption for the Atom button for a project
# Atom is a standard web feed format # Atom is a standard web feed format
#: templates/projectbase.tpl #: templates/projectbase.tpl
msgid "Atom" msgid "Atom"
msgstr "" msgstr ""
   
# Used as the title of the Atom controller # Used as the title of the Atom controller
# Atom is a standard web feed format # Atom is a standard web feed format
#: include/controller/Controller_Feed.class.php:97 #: include/controller/Controller_Feed.class.php:97
msgid "atom" msgid "atom"
msgstr "" msgstr ""
   
# Used as an error message when memcache is turned # Used as an error message when memcache is turned
# on without the appropriate PHP extension installed # on without the appropriate PHP extension installed
#: include/smartyplugins/cacheresource.memcache.php:85 #: include/smartyplugins/cacheresource.memcache.php:85
msgid "" msgid ""
"The Memcached or Memcache PHP extension is required for Memcache support" "The Memcached or Memcache PHP extension is required for Memcache support"
msgstr "" msgstr "Memcached oder die Memcache PHP Erweiterung ist notwendig für Memcache Unterstützung"
   
# Message when searching the project list, and nothing is found # Message when searching the project list, and nothing is found
# %1: the search string entered # %1: the search string entered
#: templates/jsconst.tpl #: templates/jsconst.tpl
#: templates/projectlist.tpl #: templates/projectlist.tpl
msgid "No matches found for \"%1\"" msgid "No matches found for \"%1\""
msgstr "" msgstr "Nichts gefunden zu \"%1\""
   
# Label for the field to search the project list # Label for the field to search the project list
#: templates/projectlist.tpl #: templates/projectlist.tpl
msgid "Search projects" msgid "Search projects"
msgstr "" msgstr "Durchsuche Projekte"
   
# Error message displayed when the git executable isn't found or doesn't work # Error message displayed when the git executable isn't found or doesn't work
# %1$s: the git executable the system is trying to run # %1$s: the git executable the system is trying to run
# %2$s: the config value the user needs to set to specify the correct path # %2$s: the config value the user needs to set to specify the correct path
#: index.php:140 #: index.php:140
#, php-format #, php-format
msgid "" msgid ""
"Could not run the git executable \"%1$s\". You may need to set the \"%2$s\" " "Could not run the git executable \"%1$s\". You may need to set the \"%2$s\" "
"config value." "config value."
msgstr "" msgstr ""
   
# Link displayed in commitdiff view, when the user has filtered # Link displayed in commitdiff view, when the user has filtered
# the display to a single file using the list of changed files. # the display to a single file using the list of changed files.
# This will go back to showing all files in the commitdiff # This will go back to showing all files in the commitdiff
#: templates/commitdiff.tpl #: templates/commitdiff.tpl
msgid "(show all)" msgid "(show all)"
msgstr "" msgstr "(alle anzeigen)"
   
# Message displayed when diffing two binary files. # Message displayed when diffing two binary files.
# %1$s: the filename of the first file # %1$s: the filename of the first file
# %2$s: the filename of the second file # %2$s: the filename of the second file
#: include/git/FileDiff.class.php:810 #: include/git/FileDiff.class.php:810
#, php-format #, php-format
msgid "Binary files %1 and %2 differ" msgid "Binary files %1 and %2 differ"
msgstr "" msgstr "Binäre Dateien %1 und %2 unterscheiden sich"
   
# Used to label the url of the website of the project # Used to label the url of the website of the project
#: templates/project.tpl #: templates/project.tpl
msgid "website" msgid "website"
msgstr "" msgstr "Website"
   
# This is the name of YOUR language, in your language. # This is the name of YOUR language, in your language.
# Don't just translate the word "English". # Don't just translate the word "English".
# This will be displayed as a choice in the language picker for your language. # This will be displayed as a choice in the language picker for your language.
# You want this in your native language so speakers of your language # You want this in your native language so speakers of your language
# will recognize it. For example, a french translation would translate # will recognize it. For example, a french translation would translate
# this as "Français". # this as "Français".
#: include/Resource.class.php:121 #: include/Resource.class.php:121
msgid "English" msgid "English"
msgstr "Deutsch" msgstr "Deutsch"
   
  # Indonesian translations for GitPHP package.
  # Copyright (C) 2014 Christopher Han
  # This file is distributed under the same license as the GitPHP package.
  # Samsul Ma'arif <mail@samsul.web.id>, 2014.
  #
  msgid ""
  msgstr ""
  "Project-Id-Version: GitPHP 0.2.8\n"
  "Report-Msgid-Bugs-To: xiphux@gmail.com\n"
  "POT-Creation-Date: 2012-10-28 20:33-0500\n"
  "PO-Revision-Date: 2014-06-30 02:30+0700\n"
  "Last-Translator: Samsul Ma'arif <mail@samsul.web.id>\n"
  "Language-Team: Indonesian\n"
  "Language: id\n"
  "MIME-Version: 1.0\n"
  "Content-Type: text/plain; charset=UTF-8\n"
  "Content-Transfer-Encoding: 8bit\n"
  "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
 
  # Used as link to and title for page displaying a blob, which is what git calls a single file
  #: templates/tag.tpl templates/blobdiff.tpl templates/commit.tpl
  #: templates/taglist.tpl templates/treelist.tpl templates/searchfiles.tpl
  #: templates/history.tpl include/controller/Controller_Blob.class.php:55
  msgid "blob"
  msgstr "blob"
 
  # Used as link to and title for the file history, which displays all commits that have modified a certain file
  #: templates/commit.tpl templates/treelist.tpl templates/searchfiles.tpl
  #: templates/blob.tpl include/controller/Controller_History.class.php:56
  msgid "history"
  msgstr "sejarah"
 
  # Used as title for and link to a list of files in a directory, which git calls a 'tree'
  #: templates/search.tpl templates/commit.tpl templates/headlist.tpl
  #: templates/nav.tpl templates/treelist.tpl templates/searchfiles.tpl
  #: templates/log.tpl templates/projectlist.tpl templates/shortloglist.tpl
  #: include/controller/Controller_Tree.class.php:61
  msgid "tree"
  msgstr "pohon"
 
  # Used as link to download a copy of the files in a given commit
  #: templates/search.tpl templates/commit.tpl templates/taglist.tpl
  #: templates/main.tpl templates/treelist.tpl templates/projectlist.tpl
  #: templates/shortloglist.tpl
  #: include/controller/Controller_Snapshot.class.php:121
  msgid "snapshot"
  msgstr "snapshot"
 
  # Used to label something stored in a git repository where the type of item - tag, blob, etc - isn't known
  #: templates/tag.tpl
  msgid "object"
  msgstr "objek"
 
  # Used as link to and title for page displaying info about a single commit in the project
  #: templates/tag.tpl templates/search.tpl templates/commit.tpl
  #: templates/nav.tpl templates/taglist.tpl templates/log.tpl
  #: templates/history.tpl templates/shortloglist.tpl templates/projectbase.tpl
  #: include/controller/Controller_Commit.class.php:59
  msgid "commit"
  msgstr "commit"
 
  # Used as link to and title for page displaying detailed info about a tag
  #: templates/tag.tpl templates/tagtip.tpl templates/taglist.tpl
  #: include/controller/Controller_Tag.class.php:56
  msgid "tag"
  msgstr "tanda"
 
  # Used to label the author of the commit, and as a field to search
  # The author is the person who wrote the changes in the commit
  #: templates/tag.tpl templates/commit.tpl templates/committip.tpl
  #: templates/projectbase.tpl
  msgid "author"
  msgstr "penulis"
 
  # Used as a link to a plaintext version of a page
  #: templates/blobdiff.tpl templates/commit.tpl templates/blame.tpl
  #: templates/treelist.tpl templates/commitdiff.tpl templates/blob.tpl
  msgid "plain"
  msgstr "polos"
 
  # Used as a link to a side-by-side version of a diff
  #: templates/blobdiff.tpl templates/commitdiff.tpl
  msgid "side by side"
  msgstr "berdampingan"
 
  # Used as a link to a unified version of a diff
  #: templates/blobdiff.tpl templates/commitdiff.tpl
  msgid "unified"
  msgstr "digabungkan"
 
  # Used as a link to the first page in a list of results
  #: templates/search.tpl templates/tags.tpl templates/heads.tpl
  #: templates/searchfiles.tpl templates/history.tpl
  msgid "first"
  msgstr "pertama"
 
  # Used as a link to the previous page in a list of results
  #: templates/search.tpl templates/tags.tpl templates/heads.tpl
  #: templates/searchfiles.tpl templates/log.tpl templates/history.tpl
  #: templates/shortlog.tpl
  msgid "prev"
  msgstr "sebelumnya"
 
  # Used as a link to the next page in a list of results
  #: templates/search.tpl templates/tags.tpl templates/headlist.tpl
  #: templates/taglist.tpl templates/heads.tpl templates/searchfiles.tpl
  #: templates/log.tpl templates/history.tpl templates/shortlog.tpl
  #: templates/shortloglist.tpl
  msgid "next"
  msgstr "selanjutnya"
 
  # Used as link to and title for the full diff of all the changes in a commit
  #: templates/search.tpl templates/commit.tpl templates/nav.tpl
  #: templates/log.tpl templates/history.tpl templates/shortloglist.tpl
  #: include/controller/Controller_Commitdiff.class.php:49
  msgid "commitdiff"
  msgstr "commitdiff"
 
  # Used to label the committer of the commit, and as a field to search
  # The committer is the person who put the commit into this project
  #: templates/commit.tpl templates/committip.tpl templates/projectbase.tpl
  msgid "committer"
  msgstr "peng-commit"
 
  # Used to label the parent of this commit
  # The parent is the commit preceding this one in the project history
  #: templates/commit.tpl
  msgid "parent"
  msgstr "induk"
 
  # Used to indicate the number of files changed in a commit
  # Comes before a list of files
  # %1: the number of files
  #: templates/commit.tpl templates/commitdiff.tpl
  msgid "%1 file changed:"
  msgid_plural "%1 files changed:"
  msgstr[0] "%1 berkas berubah:"
  msgstr[1] "%1 berkas berubah:"
 
  # Used to indicate a new object was added with an access mode
  # %1: the type of object
  # %2: the mode
  #: templates/commit.tpl
  msgid "new %1 with mode %2"
  msgstr "%1 baru dengan mode %2"
 
  # Used to indicate a new object was added
  # %1: the type of object
  #: templates/commit.tpl
  msgid "new %1"
  msgstr "%1 baru"
 
  # Used to indicate an object was deleted
  # %1: the type of object
  #: templates/commit.tpl
  msgid "deleted %1"
  msgstr "%1 dihapus"
 
  # Used to indicate a file type changed, including original and new file modes
  # (when both original and new files are regular files)
  # %1: the original file type
  # %2: the new file type
  # %3: the original file mode
  # %4: the new file mode
  #: templates/commit.tpl
  msgid "changed from %1 to %2 mode: %3 -> %4"
  msgstr "berubah dari %1 ke %2 mode: %3 -> %4"
 
  # Used to indicate a file type changed, with only new file mode
  # (when old file type wasn't a normal file)
  # %1: the original file type
  # %2: the new file type
  # %3: the original file mode
  # %4: the new file mode
  #: templates/commit.tpl
  msgid "changed from %1 to %2 mode: %3"
  msgstr "berubah dari %1 ke %2 mode: %3"
 
  # Used to indicate a file type changed
  # %1: the original file type
  # %2: the new file type
  #: templates/commit.tpl
  msgid "changed from %1 to %2"
  msgstr "berubah dari %1 ke %2"
 
  # Used to indicate a file mode changed
  # %1: the original file mode
  # %2: the new file mode
  #: templates/commit.tpl
  msgid "changed mode: %1 -> %2"
  msgstr "mode berubah: %1 -> %2"
 
  # Used to indicate a file mode changed
  # %1: the new file mode
  #: templates/commit.tpl
  msgid "changed mode: %1"
  msgstr "mode berubah: %1"
 
  # Used to indicate a file mode changed
  #: templates/commit.tpl
  msgid "changed"
  msgstr "berubah"
 
  # Used as link to diff this file version with the previous version
  #: templates/commit.tpl templates/history.tpl
  msgid "diff"
  msgstr "diff"
 
  # Used to indicate a file was moved and the file mode changed
  # This string should be HTML safe
  # %1: the old file
  # %2: the similarity as a percent number
  # %3: the new file mode
  #: templates/commit.tpl
  msgid "moved from %1 with %2%% similarity, mode: %3"
  msgstr "pindah dari %1 dengan kemiripan %2%%, mode : %3"
 
  # Used to indicate a file was moved
  # This string should be HTML safe
  # %1: the old file
  # %2: the similarity as a percent number
  #: templates/commit.tpl
  msgid "moved from %1 with %2%% similarity"
  msgstr "pindah dari %1 dengan kemiripan %2%%"
 
  # Used as title for and link to the compact log view with one line abbreviated commits
  #: templates/headlist.tpl templates/nav.tpl templates/taglist.tpl
  #: templates/title.tpl templates/projectlist.tpl
  #: include/controller/Controller_Log.class.php:60
  msgid "shortlog"
  msgstr "log pendek"
 
  # Used as title for and link to log view with full commit messages
  #: templates/headlist.tpl templates/nav.tpl templates/taglist.tpl
  #: templates/projectlist.tpl include/controller/Controller_Log.class.php:65
  msgid "log"
  msgstr "log"
 
  # Used as title for and link to project summary page
  #: templates/nav.tpl templates/projectlist.tpl
  #: include/controller/Controller_Project.class.php:42
  msgid "summary"
  msgstr "ringkasan"
 
  # Link back to the list of projects
  #: templates/login.tpl templates/main.tpl templates/projectbase.tpl
  #: include/controller/ControllerBase.class.php:519
  #: include/controller/Controller_ProjectList.class.php:78
  msgid "projects"
  msgstr "proyek"
 
  # Used as a search type, to search the contents of files in the project
  #: templates/projectbase.tpl
  #: include/smartyplugins/function.localfiletype.php:29
  msgid "file"
  msgstr "berkas"
 
  # Used as title for search page, and also is the label for the search box
  #: templates/projectbase.tpl
  #: include/controller/Controller_Search.class.php:108
  msgid "search"
  msgstr "cari"
 
  # Used as a link to the HEAD of a project for a log or file
  # (note: HEAD is standard git terminology)
  #: templates/blame.tpl templates/log.tpl templates/shortlog.tpl
  #: templates/blob.tpl
  msgid "HEAD"
  msgstr "HEAD"
 
  # Used to indicate the last change in a project
  # %1: the timestamp of the latest change
  #: templates/log.tpl
  msgid "Last change %1"
  msgstr "Perubahan terakhir %1"
 
  # Message displayed when there are no commits in the project to display
  #: templates/log.tpl templates/projectlist.tpl templates/shortloglist.tpl
  msgid "No commits"
  msgstr "Tidak ada commit"
 
  # Used as link to diff this file version with the current file
  #: templates/history.tpl
  msgid "diff to current"
  msgstr "diff ke terkini"
 
  # Used as link to and title for page showing all tags in a project
  #: templates/title.tpl include/controller/Controller_Tags.class.php:53
  msgid "tags"
  msgstr "tag"
 
  # Used as link to and title for page showing all heads in a project
  #: templates/title.tpl include/controller/Controller_Heads.class.php:53
  msgid "heads"
  msgstr "head"
 
  # Used when diffing a file, to indicate that it's been deleted
  #: templates/commitdiff.tpl
  msgid "(deleted)"
  msgstr "(dihapus)"
 
  # Used when diffing a file, to indicate that it's a new file
  #: templates/commitdiff.tpl
  msgid "(new)"
  msgstr "(baru)"
 
  # Used to label the project description
  #: templates/project.tpl
  msgid "description"
  msgstr "penjelasan"
 
  # Used to label the project owner
  #: templates/project.tpl
  msgid "owner"
  msgstr "pemilik"
 
  # Used to label the time the project was last changed
  # (the time of the most recent commit)
  #: templates/project.tpl
  msgid "last change"
  msgstr "perubahan terakhir"
 
  # Used to label the url that users can use to clone the project
  #: templates/project.tpl
  msgid "clone url"
  msgstr "url kloning"
 
  # Used to label the url that users can use to push commits to the project
  #: templates/project.tpl
  msgid "push url"
  msgstr "url push"
 
  # Used as the header for the project name column
  #: templates/projectlist.tpl
  msgid "Project"
  msgstr "Proyek"
 
  # Used as the header for the project description column
  #: templates/projectlist.tpl
  msgid "Description"
  msgstr "Penjelasan"
 
  # Used as the header for the column showing the person that owns the project
  #: templates/projectlist.tpl
  msgid "Owner"
  msgstr "Pemilik"
 
  # Used as the header for the last change column
  # (how long ago was the last commit)
  #: templates/projectlist.tpl
  msgid "Last Change"
  msgstr "Perubahan Terakhir"
 
  # Used as the header for the actions column, which is a list of links users can use to jump to various parts of this project
  #: templates/projectlist.tpl
  msgid "Actions"
  msgstr "Aksi"
 
  # Message shown when there were no projects found to display
  #: templates/projectlist.tpl
  msgid "No projects found"
  msgstr "Proyek tidak ditemukan"
 
  # Used as link to and title for page displaying blame info (who last touched what line) in a file
  #: templates/blob.tpl include/controller/Controller_Blame.class.php:59
  msgid "blame"
  msgstr "blame"
 
  # Error message when user tries to do an action that requires a project but a project isn't specified
  #: include/controller/Controller_Message.class.php:150
  msgid "Project is required"
  msgstr "Proyek diperlukan"
 
  # Used as the title of the rss controller
  # rss is a standard web feed format
  #: include/controller/Controller_Feed.class.php:77
  msgid "rss"
  msgstr "rss"
 
  # Used as link to and title for a diff of a single file
  #: include/controller/Controller_Blobdiff.class.php:45
  msgid "blobdiff"
  msgstr "blobdiff"
 
  # Error message when user tries to access a project that doesn't exist
  # %1$s: the project the user tried to access
  #: include/controller/Controller_Message.class.php:144
  #, php-format
  msgid "Invalid project %1$s"
  msgstr "Proyek tidak sesuai %1$s"
 
  # Used as the title for the opml controller
  # OPML is a standard XML outline format
  #: include/controller/Controller_ProjectList.class.php:68
  msgid "opml"
  msgstr "opml"
 
  # Used as the title of the project index controller
  #: include/controller/Controller_ProjectList.class.php:73
  msgid "project index"
  msgstr "indeks proyek"
 
  # Error message when a user tries to search but searching has been disabled in the config
  #: include/controller/Controller_Message.class.php:161
  msgid "Search has been disabled"
  msgstr "Pencarian dinonaktifkan"
 
  # Error message when a user tries to do a file search but searching files has been disabled in the config
  #: include/controller/Controller_Message.class.php:157
  msgid "File search has been disabled"
  msgstr "Pencarian berkas dinonaktifkan"
 
  # Error message when a user's search query is too short
  # %1$d: the minimum number of characters
  #: include/controller/Controller_Message.class.php:174
  #, php-format
  msgid "You must enter search text of at least %1$d character"
  msgid_plural "You must enter search text of at least %1$d characters"
  msgstr[0] "Anda harus memasukkan teks pencarian setidaknya %1$d karakter"
  msgstr[1] "Anda harus memasukkan teks pencarian setidaknya %1$d karakter"
 
  # Error message when the user enters an unsupported search type
  #: include/controller/Controller_Message.class.php:168
  msgid "Invalid search type"
  msgstr "Tipe pencarian salah"
 
  # Error message when a user's search didn't produce any results
  # %1$s: the user's search string
  #: templates/search.tpl templates/searchfiles.tpl
  #, php-format
  msgid "No matches for \"%1\""
  msgstr "\"%1\" tidak ditemukan"
 
  # A type of filesystem object stored in a project
  #: include/smartyplugins/function.localfiletype.php:41
  msgid "directory"
  msgstr "direktori"
 
  # A type of filesystem object stored in a project
  #: include/smartyplugins/function.localfiletype.php:35
  msgid "symlink"
  msgstr "tautan simbolik"
 
  # Used when an object is stored in a project but git doesn't know what type it is
  #: include/smartyplugins/function.localfiletype.php:47
  msgid "unknown"
  msgstr "tidak diketahui"
 
  # Error message when user specifies a path for a project root or project, but the path given isn't a directory
  # %1$s: the path the user specified
  #: include/controller/Controller_Message.class.php:204
  #, php-format
  msgid "%1$s is not a directory"
  msgstr "%1$s bukan sebuah direktori"
 
  # Error message when a path specified in the config is not a git repository
  # %1$s: the specified path
  #: include/controller/Controller_Message.class.php:216
  #, php-format
  msgid "%1$s is not a git repository"
  msgstr "%1$s bukan repositori git"
 
  # Error message when a path specified is using '..' to break out of the project root (a hack attempt)
  # %1$s: The specified path
  #: include/controller/Controller_Message.class.php:228
  #, php-format
  msgid "%1$s is attempting directory traversal"
  msgstr "%1$s mencoba direktori traversal"
 
  # Error message when a path specified is outside of the project root
  # %1$s: The specified path
  #: include/controller/Controller_Message.class.php:234
  #, php-format
  msgid "%1$s is outside of the projectroot"
  msgstr "%1$s di luar akar proyek"
 
  # Error message when user tries to specify a file with a list of the projects, but it isn't a file
  # %1$s: the path the user specified
  #: include/controller/Controller_Message.class.php:210
  #, php-format
  msgid "%1$s is not a file"
  msgstr "%1$s bukan sebuah berkas"
 
  # Error message when user tries to specify a file with a list of the projects, but the system can't read the file
  # %1$s: the file the user specified
  #: include/controller/Controller_Message.class.php:222
  #, php-format
  msgid "Failed to open project list file %1$s"
  msgstr "Gagal membuka berkas daftar proyek %1$s"
 
  # Error message when a hash specified in a URL isn't a valid git hash
  # %1$s: the hash entered
  #: include/controller/Controller_Message.class.php:180
  #, php-format
  msgid "Invalid hash %1$s"
  msgstr "Hash tidak sesuai %1$s"
 
  # Used to represent an age in years
  # %1$d: the number of years
  #: include/smartyplugins/function.agestring.php:31
  #, php-format
  msgid "%1$d year ago"
  msgid_plural "%1$d years ago"
  msgstr[0] "%1$s tahun lalu"
  msgstr[1] "%1$s tahun lalu"
 
  # Used to represent an age in months
  # %1$d: the number of months
  #: include/smartyplugins/function.agestring.php:39
  #, php-format
  msgid "%1$d month ago"
  msgid_plural "%1$d months ago"
  msgstr[0] "%1$d bulan lalu"
  msgstr[1] "%1$d bulan lalu"
 
  # Used to represent an age in weeks
  # %1$d: the number of weeks
  #: include/smartyplugins/function.agestring.php:47
  #, php-format
  msgid "%1$d week ago"
  msgid_plural "%1$d weeks ago"
  msgstr[0] "%1$d minggu lalu "
  msgstr[1] "%1$d minggu lalu"
 
  # Used to represent an age in days
  # %1$d: the number of days
  #: include/smartyplugins/function.agestring.php:55
  #, php-format
  msgid "%1$d day ago"
  msgid_plural "%1$d days ago"
  msgstr[0] "%1$d hari lalu"
  msgstr[1] "%1$d hari lalu"
 
  # Used to represent an age in hours
  # %1$d: the number of hours
  #: include/smartyplugins/function.agestring.php:63
  #, php-format
  msgid "%1$d hour ago"
  msgid_plural "%1$d hours ago"
  msgstr[0] "%1$d jam lalu"
  msgstr[1] "%1$d jam lalu"
 
  # Used to represent an age in minutes
  # %1$d: the number of minutes
  #: include/smartyplugins/function.agestring.php:71
  #, php-format
  msgid "%1$d min ago"
  msgid_plural "%1$d min ago"
  msgstr[0] "%1$d menit lalu"
  msgstr[1] "%1$d menit lalu"
 
  # Used to represent an age in seconds
  # %1$d: the number of seconds
  #: include/smartyplugins/function.agestring.php:79
  #, php-format
  msgid "%1$d sec ago"
  msgid_plural "%1$d sec ago"
  msgstr[0] "%1$d detik lalu"
  msgstr[1] "%1$d detik lalu"
 
  # Used to represent a modification time of right now
  #: include/smartyplugins/function.agestring.php:86
  msgid "right now"
  msgstr "sekarang"
 
  # Error message when user hasn't defined a project root in the config
  # "projectroot" refers to a root directory where the user's git projects are stored
  #: include/controller/Controller_Message.class.php:192
  msgid "A projectroot must be set in the config"
  msgstr "Sebuah proyek harud ditetapkan di konfigurasi"
 
  # Caption for the rss button for a project
  # rss is a standard web feed format
  #: templates/projectbase.tpl
  msgid "RSS"
  msgstr "RSS"
 
  # Caption for the OPML button on the project list
  # OPML is a standard XML outline format
  #: templates/projectlist.tpl
  msgid "OPML"
  msgstr "OPML"
 
  # Caption for the button to get a plaintext list of projects
  #: templates/projectlist.tpl
  msgid "TXT"
  msgstr "TXT"
 
  # Label for the selected commit, when selecting commits to diff
  #: templates/log.tpl templates/shortlog.tpl
  msgid "selected"
  msgstr "terpilih"
 
  # Link to deselect the currently selected diff
  #: templates/log.tpl templates/shortlog.tpl templates/shortloglist.tpl
  msgid "deselect"
  msgstr "batalkan pilihan"
 
  # Link beside commits - diffs this commit against the currently selected commit
  #: templates/log.tpl templates/shortloglist.tpl
  msgid "diff with selected"
  msgstr "diff yang terpilih"
 
  # Link beside commits - selects this commit to be used in a diff
  #: templates/log.tpl templates/shortloglist.tpl
  msgid "select for diff"
  msgstr "pilih untuk diff"
 
  # Used as an alternate text on javascript "loading" images
  #: templates/main.tpl templates/projectlist.tpl
  msgid "Loading…"
  msgstr "Memuat..."
 
  # Used as a loading message while blame data is being pulled from the server
  #: templates/main.tpl
  msgid "Loading blame data…"
  msgstr "Memuat data blame..."
 
  # Used as a label by the language selector drop-down box
  #: templates/main.tpl
  msgid "language:"
  msgstr "Bahasa:"
 
  # Used as a button by the language selector drop-down box to set the
  # language to the user's choice
  #: templates/main.tpl
  msgid "set"
  msgstr "tetapkan"
 
  # Caption for the Atom button for a project
  # Atom is a standard web feed format
  #: templates/projectbase.tpl
  msgid "Atom"
  msgstr "Atom"
 
  # Used as the title of the Atom controller
  # Atom is a standard web feed format
  #: include/controller/Controller_Feed.class.php:82
  msgid "atom"
  msgstr "atom"
 
  # Used as an error message when memcache is turned
  # on without the appropriate PHP extension installed
  #: include/controller/Controller_Message.class.php:198
  msgid ""
  "The Memcached or Memcache PHP extension is required for Memcache support"
  msgstr ""
  "Memcached atau ekstensi PHP Memchace diperlukan untuk dukungan Memcache"
 
  # Message when searching the project list, and nothing is found
  # %1: the search string entered
  #: templates/main.tpl templates/projectlist.tpl
  msgid "No matches found for \"%1\""
  msgstr "Tidak ditemukan untuk \"%1\""
 
  # Label for the field to search the project list
  #: templates/projectlist.tpl
  msgid "Search projects"
  msgstr "Cari proyek"
 
  # Error message displayed when the git executable isn't found or doesn't work
  # %1$s: the git executable the system is trying to run
  # %2$s: the config value the user needs to set to specify the correct path
  #: include/controller/Controller_Message.class.php:186
  #, php-format
  msgid ""
  "Could not run the git executable \"%1$s\". You may need to set the \"%2$s\" "
  "config value."
  msgstr ""
  "Tidak dapat mengeksekusi \"%1$s\". Anda mungkin perlu menetapkan nilai"
  "\"%2$s\"."
 
  # Link displayed in commitdiff view, when the user has filtered
  # the display to a single file using the list of changed files.
  # This will go back to showing all files in the commitdiff
  #: templates/commitdiff.tpl
  msgid "(show all)"
  msgstr "(perlihatkan semua)"
 
  # Message displayed when diffing two binary files.
  # %1$s: the filename of the first file
  # %2$s: the filename of the second file
  #: templates/blobdiff.tpl templates/blobdiffplain.tpl templates/commitdiff.tpl
  #, php-format
  msgid "Binary files %1 and %2 differ"
  msgstr "Differ berkas biner %1 dan %2"
 
  # Used to label the url of the website of the project
  #: templates/project.tpl
  msgid "website"
  msgstr "website"
 
  # This is the name of YOUR language, in your language.
  # Don't just translate the word "English".
  # This will be displayed as a choice in the language picker for your language.
  # You want this in your native language so speakers of your language
  # will recognize it. For example, a french translation would translate
  # this as "Français".
  #: include/Resource.class.php:130
  msgid "English"
  msgstr "Bahasa Indonesia"
 
  # Message when the config file failed to load
  # %1$s: the config file that we tried to load
  #: include/controller/Controller_Message.class.php:240
  #, php-format
  msgid "Could not load config file %1$s"
  msgstr "Tidak dapat memuat berkas konfigurasi %1$s"
 
  # Used as a link to and title of the graph page
  #: include/controller/Controller_Graph.class.php:56
  msgid "graph"
  msgstr "grafik"
 
  # Name of the commit activity graph
  #: templates/graph.tpl
  msgid "commit activity"
  msgstr "aktifitas commit"
 
  # Name of the language distribution graph
  #: templates/graph.tpl
  msgid "language distribution"
  msgstr "distribusi bahasa"
 
  # Message displayed when an abbreviated hash is given
  # but it is ambiguous because there are multiple hashes
  # in the system with this abbreviation
  #: include/controller/Controller_Message.class.php:246
  #, php-format
  msgid "Ambiguous abbreviated hash %1$s"
  msgstr "Hash %1$s singkatan membingungkan"
 
  # Message displayed when a directory that doesn't exist
  # is specified
  #: include/controller/Controller_Message.class.php:253
  #, php-format
  msgid "Directory %1$s not found"
  msgstr "Direktori %1$s tidak ditemukan"
 
  # Message displayed when a file that doesn't exist is
  # specified
  #: include/controller/Controller_Message.class.php:260
  #, php-format
  msgid "File %1$s not found"
  msgstr "Berkas %1$s tidak ditemukan"
 
  # Label for the username field on the login form
  #: templates/login.tpl templates/main.tpl
  msgid "username:"
  msgstr "nama pengguna:"
 
  # Label for the password field on the login form
  #: templates/login.tpl templates/main.tpl
  msgid "password:"
  msgstr "kata sandi:"
 
  # Label for the link/button for a user to login to an account
  #: templates/login.tpl templates/main.tpl
  #: include/controller/Controller_Login.class.php:67
  msgid "login"
  msgstr "masuk"
 
  # Label for the link for a user to log out of an account
  # %1: the account username
  #: templates/main.tpl
  msgid "logout %1"
  msgstr "keluar %1"
 
  # Error message that appears when there is a technical error
  # during login
  #: templates/main.tpl
  msgid "An error occurred while logging in"
  msgstr "Ada kesalahan ketika masuk"
 
  # Title of the login modal message box
  #: templates/main.tpl
  msgid "Login"
  msgstr "Masuk"
 
  # Error message when the username or the password is
  # invalid (login failure)
  #: include/controller/Controller_Login.class.php:124
  #: include/controller/Controller_Login.class.php:150
  msgid "Invalid username or password"
  msgstr "Nama pengguna atau kata sandi tidak sesuai"
 
  # Error message when a username is not entered during login
  #: templates/main.tpl
  msgid "Username is required"
  msgstr "Nama pengguna diperlukan"
 
  # Error message when a password is not entered during login
  #: templates/main.tpl
  msgid "Password is required"
  msgstr "Kata sandi diperlukan"
 
  # Error message when a user tries to access a project they
  # don't have access to
  # %1$s: The project they tried to access
  #: include/controller/Controller_Message.class.php:267
  #, php-format
  msgid "You are not authorized to access project %1$s"
  msgstr "Anda tidak diizinkan mengakses proyek %1$s"
 
  # Error message when a function required by gitphp
  # has been disabled in the php config
  # %1$s: The name of the function
  #: include/controller/Controller_Message.class.php:274
  #, php-format
  msgid "Required function %1$s has been disabled"
  msgstr "Fungsi yang diperlukan %1$s telah dinonaktifkan"
 
comments