我在一家小型的php商店工作,最近我提议我们不再使用我们的nas作为共享代码库,而是开始使用subversion进行源代码控制。
我已经想出如何确保我们的开发服务器在每次提交到我们的开发分支时都会更新...我知道如何合并到trunk并让我们更新我们的登台服务器,因为我们可以直接访问其中,但我最大的问题是如何编写一个脚本来更新生产服务器,我们很多时候只能访问ftp。我不想每次都上传整个网站...有没有办法编写一个足够智能的脚本,只在我们执行它时只上传已更改为Web服务器的内容(不希望它自动成为上传到生产环境,我们想手动执行它??
我的问题是否有意义?
答案 0 :(得分:4)
基本上,您的问题是您无法在生产服务器上使用subversion。您需要做的是在一个单独的(理想情况下配置相同的)服务器上保留生产结帐的副本,并通过任何方法将其复制到生产服务器。实际上,您可以将此视为您的临时服务器,因为在将它们推出之前对它们进行最终测试也很有用。
就副本而言,如果您的提供商支持rsync
,则您已设置。如果你只有FTP,你必须找到一些通过FTP进行rsync等效的方法。这不是任何人第一次有这种需要;网络搜索将帮助您。但是,如果你找不到任何东西,请给我留言,我会更进一步环顾四周。
编辑:希望作者不介意我添加这个,但我认为它属于这里。要使用ftp执行与rsync类似的操作,请查看weex http://weex.sourceforge.net/。它是命令行ftp的包装器,它使用本地镜像跟踪远程服务器上的什么,以便它只能发送更改的文件。对我很有用。
答案 1 :(得分:1)
它doesn't sound like SVN可以很好地与FTP配合使用,但是如果您有http访问权限,则可能足以使用svnsync推送更改。这就是我们如何推动对生产服务器的更改 - 我们使用svnsync来保持存储库的只读镜像。
答案 2 :(得分:1)
我使用以下解决方案。只需在您的网络服务器上安装SVN客户端,并将其附加到可私人访问的URL:
<?php
// make sure you have a robot account that can't commit ;)
$username = Settings::Load()->Get('svn', 'username');
$password = Settings::Load()->Get('svn', 'password');
$repos = Settings::Load()->Get('svn', 'repository');
echo '<h1>updating from svn</h1><pre>';
// for secutity, define an array of folders that you do want to be synced from svn. The rest should be skipped.
$svnfolders = array( 'includes/' ,'plugins/' ,'images/' ,'templates/', 'index.php' => 'index.php');
if(!empty($_GET['justthisone']) && array_search($_GET['justthisone'], $svnfolders) !== false){ // you can also just update one of above by passing it to $_GET
$svnfiles = array($_GET['justthisone']);
}
foreach($svnfiles as $targetlocation)
{
echo system("svn export --username={$username} --password {$password} {$repos}{$targetlocation} ".dirname(__FILE__)."/../{$targetlocation} --force");
}
die("</pre><h1>Done!</h1>");
答案 3 :(得分:0)
我将在这里做一个假设,并说你正在使用一个post-commit钩子来进行你的登台服务器的合并/更新。这可能有用,但我强烈建议您查看Continuous Integration解决方案。以下是我所知道的一些内容:
答案 4 :(得分:0)
LFTP能够通过ftp同步目录。
答案 5 :(得分:0)
只是一个想法:
您可以在您有权访问的主机上以及安装了Subversion的位置保留项目的修订版。此单个版本反映了生产服务器的版本。 您现在可以编写一个PHP脚本,通过svn更新此存储库,然后查找自更新代表以来已更改的所有文件。您可以上传这些文件。
这样的脚本可能如下所示:
$path = realpath( '/path/to/production/mirror' );
chdir( $path );
$start = time();
shell_exec( 'svn co' );
$list = array();
$i = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $path ), RecursiveIteratorIterator::SELF_FIRST );
foreach( $i as $node )
{
if ( $node->isFile() && $node->getCTime() > $start )
{
$list[] = $node->getPathname();
}
// directories should also be handled
}
$conn = ftp_connect( ... );
// and so on
就像我想到的那样。
答案 6 :(得分:0)