2012-07-27 61 views
1

在Subversion 1.6中,每個工作副本目錄中都有一個.svn目錄。我可以使用下面的代碼快速檢索當前版本號,而不需要shell訪問/執行。在PHP中可移植地檢索Subversion 1.7修訂版?

public function getSubversionRevision() { 
    if(file_exists("../.svn/entries")) { 
     $svn = File("../.svn/entries"); 
     return (int)$svn[3]; 
    } 
    return false; 
} 

Subversion 1.7打破了這段代碼。每個本地存儲庫現在只有一個.svn目錄。有entries文件在這個目錄中,但它不再有任何有用的東西。它看起來像我需要的一切現在在SQLite數據庫中。具體爲wc.db。我想我可以使用PHP的SQLite函數獲取我需要的信息,但這聽起來有點過於昂貴,無法在每次(或接近每次)頁面加載時運行。

任何想法?打破exec函數並希望安裝Subversion二進制文件(並在$ PATH!中)是最後的手段。總而言之,我需要找到一種方法來找到存儲庫根目錄下的.svn目錄(根據您的簽出位置可能有所不同),然後以經濟高效的方式解析文件(可能爲wc.db)。

+0

你使用的是什麼操作系統獲取的svnversion? – 2012-07-27 06:06:08

+0

Linux是目標操作系統。目標是儘可能使代碼儘可能便攜,以使操作系統和該操作系統的特定配置在最大程度上無關緊要。 – 2012-07-27 06:08:38

+0

從操作系統到操作系統,我看不到很多可移植性的使用。如果你正在嘗試在Linux上使用它,你可以每次爲你寫一個腳本到'svn update',並且將更新的輸出中的修訂版號刪除到一個文件中。 'svn - 非交互式更新..'然後 'svn - 非交互式更新.. | perl -p -e「s /.* revision([\ d] *)\ ./ \ $ 1 /」> ../ version.phtml;' – 2012-07-27 06:26:02

回答

1

每次都可以編寫一個腳本來svn update你和廢料從更新的輸出版本號到文件中。下面的bash腳本應該或多或少地做到這一點:

#!/bin/bash 

svn --non-interactive update .. 
svn --non-interactive update .. | perl -p -e "s/.* revision ([\d]*)\./\$1/" > ../version.phtml; 
+0

這是我必須要做的,直到PECL SVN庫被修補以與Subversion 1.7一起工作。在我的特殊用例中,我不需要自動更新。我保持原來的1.6代碼完整,並使用shell執行作爲後備(本質上,如果它不是1.6,那麼嘗試shell命令)。 – 2012-07-27 08:51:34

2

嘗試使用SVN庫SVN,因爲它可以讓您訪問存儲庫信息和SVN存儲庫上的更多功能。
看看功能svn_status您將收到和SVN倉庫信息數組

Array (
    [0] => Array (
     [path] => /home/bob/wc/sandwich.txt 
     [text_status] => 8 // item was modified 
     [repos_text_status] => 1 // no information available, use update 
     [prop_status] => 3 // no changes 
     [repos_prop_status] => 1 // no information available, use update 
     [name] => sandwich.txt 
     [url] => http://www.example.com/svnroot/deli/trunk/sandwich.txt 
     [repos] => http://www.example.com/svnroot/ 
     [revision] => 123 // <-- Current Revision 
     //.. 
    ) 
) 
+0

不幸的是,我無法讓PECL SVN庫在Subversion 1.7之上編譯。 – 2012-07-27 07:21:52

1

我實現了一個笨拙的(但相對透徹)實施顛覆1.7版本檢索的TheHostingTool。檢查提交消息以獲取解釋。該函數包含在class_main.php中,後者是/ trunk(/trunk/includes/class_main.php)之後的一個目錄。您需要根據您的特定需求調整相對路徑。這是在class_main.php中找到的用於別處的函數的稍微修改過的版本。

public function getSubversionRevision() { 
    // This will work for Subverson 1.6 clients and below 
    if(file_exists("../.svn/entries")) { 
     $svn = File("../.svn/entries"); 
     return (int)$svn[3]; 
    } 
    // Check the previous directories recursively looking for wc.db (Subversion 1.7) 
    $searchDepth = 3; // Max search depth 
    // Do we have PDO? And do we have the SQLite PDO driver? 
    if(!extension_loaded('PDO') || !extension_loaded('pdo_sqlite')) { 
     $searchDepth = 0; // Don't even bother... 
    } 
    for($i = 1; $i <= $searchDepth; $i++) { 
     $dotdot .= '../'; 
     if(!file_exists("$dotdot.svn/wc.db")) { 
      continue; 
     } 
     $wcdb = new PDO("sqlite:$dotdot.svn/wc.db"); 
     $result = $wcdb->query('SELECT "revision" FROM "NODES" WHERE "repos_path" = "'.basename(realpath('..')).'"'); 
     return (int)$result->fetchColumn(); 
    } 
    if($this->canRun('exec')) { 
     exec('svnversion ' . realpath('..'), $out, $return); 
     // For this to work, svnversion must be in your PHP's PATH enviroment variable 
     if($return === 0 && $out[0] != "Unversioned directory") { 
      return (int)$out[0]; 
     } 
    } 
    return false; 
} 

而不是.= '../'你可能想用str_repeat如果不從1開始或者,你可以簡單地定義$dotdot的時間提前,無論你想開始。

+0

如果你想獲得最後修改的版本號,請將'SELECT「修訂版''更改爲'SELECT」changed_revision「' – 2012-11-04 02:56:56

0

或者只是查詢:

SELECT "changed_revision" FROM "NODES" ORDER BY changed_revision DESC LIMIT 1; 

,如果你想知道整個回購的最後一個版本! :)

0

對不起,但如果你想要便攜和防彈解決方案,爲什麼不在PHP中調用Subversion CLI?

可以使用svn info WC的任何目錄中(採集,分析輸出,並得到一組數據),如果你想全球唯一版本

+0

這不完全是可移植的。他們可以安裝SVN,而不需要將其放入PHP查找的PATH中。我在該解決方案中使用了該選項作爲備份。 – 2013-03-29 04:04:05