有没有一个好的 php git 客户端,支持 http?

发布于 2025-01-05 07:59:21 字数 1539 浏览 1 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夏有森光若流苏 2025-01-12 07:59:21

https://github.com/kbjr/Git.php

Git.php 是一个包装类git 调用使用 proc_open 而不是 exec 来运行命令。虽然它没有推/拉方法,但它确实有一个用于运行自定义 git 命令的通用 run 方法,因此可以像这样使用它:

$repo = Git::open('/path/to/repo');
$repo->run('push origin master');

它也有用于克隆的方法(clone_toclone_from 进行本地克隆,clone_remote 进行远程克隆)。

https://github.com/kbjr/Git.php

Git.php is a wrapper class around git calls that uses proc_open instead of exec to run the commands. While it does not have push/pull methods, it does have a general run method for running custom git commands, so it could be used something like this:

$repo = Git::open('/path/to/repo');
$repo->run('push origin master');

It also does have methods for cloning (clone_to and clone_from which do local cloning and clone_remote for remote cloning).

羁客 2025-01-12 07:59:21

一种可能性是使用 PHP 的 SSH 库通过连接回 Web 服务器来执行这些操作?

或者我发现这组类 允许您通过 HTTP 克隆和读取其他元数据,但不能推送或拉取。然而,如果您有足够的勇气扩展它们来做到这一点,那么这可能是一个起点。我可以想象复制这些流程并使其与各种服务器版本等兼容将需要大量工作。

[更新2014年3月23日,在收到赞成票后 - 谢谢!]

我确实找到了一些方法来尝试实现上述内容(我正在寻找一个实现,画了一个空白,所以尝试编写自己的),并且正如我想象的那样很难!实际上我放弃了它,因为我找到了一种更简单的方法来在不同的架构中实现这一目标,但这是我尝试编写的类。它本质上是有效的,但对我工作的环境变化很脆弱(即它不能很好地处理错误或问题)。

它使用:

  1. herzult/php-ssh
  2. 一个 ssh 配置文件 - 一个简化在代码中设置身份验证凭据的技巧

(注意 - 我必须快速从代码中删除一些细节才能发布它。所以你需要摆弄将其集成到您的应用程序/命名空间等中)

<?php
/**
 * @author: scipilot
 * @since: 31/12/2013
 */

/**
 * Class GitSSH allows you to perform Git functions over an SSH session.
 * i.e. you are using the command-line Git commands after SSHing to a host which has the Git client.
 *
 * You don't need to know about the SSH to use the class, other than the fact you will need access
 * to a server via SSH which has the Git client installed. Its likely this is the local web server.
 *
 * This was made because PHP has no good native Git client.
 *
 * Requires herzult/php-ssh
 *
 * Example php-ssh config file would be
 *
 * <code>
 *  Host localhost
 *  User git
 *  IdentityFile id_rsa
 *
 *  Host your.host.domain.com
 *  User whoever
 *  IdentityFile ~/.ssh/WhoeverGit
 *</code>
 */
class GitSSH {
    protected $config;
    protected $session;
    protected $sPath;
    /**
     * @var string
     */
    protected $sConfigPath = '~/.ssh/config';

    /**
     * Connects to the specified host, ready for further commands.
     *
     * @param string $sHost         Host (entry in the config file) to connect to.
     * @param string $sConfigPath Optional; config file path. Defaults to ~/.ssh/config,
     *                            which is probably inaccessible for web apps.
     */
    function __construct($sHost, $sConfigPath=null){
        \Log::info('New GitSSH '.$sHost.', '.$sConfigPath);
        if(isset($sConfigPath)) $this->sConfigPath = $sConfigPath;

        $this->config = new \Ssh\SshConfigFileConfiguration($this->sConfigPath, $sHost);
        $this->session = new \Ssh\Session($this->config, $this->config->getAuthentication());
    }

    public function __destruct() {
        $this->disconnect();
    }

    /**
     * Thanks to Steve Kamerman, as there isn't a native disconnect.
     */
    public function disconnect() {
        $this->exec('echo "EXITING" && exit;');
        $this->session = null;
    }

    /**
     * Run a command (in the current working directory set by cd)
     * @param $sCommand
     * @return string
     */
    protected function exec($sCommand) {
        //echo "\n".$sCommand."\n";
        $exec = $this->session->getExec();
        $result = $exec->run('cd '.$this->sPath.'; '.$sCommand);
        // todo: parse/scrape the result, return a Result object?
        return $result;
    }

    /**
     * CD to a folder. (This not an 'incremental' cd!)
     * Devnote: we don't really execute the cd now, it's appended to other commands. Each command seems to re-login?
     *
     * @param string $sPath Absolute filesystem path, or relative from user home
     */
    public function cd($sPath){
        $this->sPath = $sPath;

        // @todo this is useless! each command seems to run in a separate login?
        //$result = $this->exec('cd'); // /; ls');
        //return $result;
    }

    /**
     * @return string
     */
    public function ls(){
        $result = $this->exec('ls ');

        return $result;
    }

    public function gitAdd($sOptions=null, array $aFiles=null){
        $result = $this->exec('git add '
            .(empty($sOptions) ? '' : ' '.$sOptions)
            .(empty($aFiles) ? '' : ' '.implode(' ', $aFiles))
        );

        return $result;
    }

    public function gitClone($sRepo, $sBranch=null, $sTarget=null){
        \Log::info('GitSSH::clone '.$sRepo.', '.$sBranch.', '.$sTarget);
        $result = $this->exec('git clone '
            .(empty($sBranch) ? '' : ' --branch '.$sBranch)
            .' '.$sRepo
            .' '.$sTarget);

        return $result;
    }

    public function gitCommit($sMessage, $sOptions=null, array $aFiles=null){
        $result = $this->exec('git commit '
            .'-m "'.addcslashes($sMessage, '"').'"'
            .(empty($sOptions) ? '' : ' '.$sOptions)
            .(empty($aFiles) ? '' : ' '.implode(' ', $aFiles))
        );

        return $result;
    }

    public function gitPull($sOptions=null, $sRepo=null, $sRefspec=null){
        $result = $this->exec('git pull '
            .(empty($sOptions) ? '' : ' '.$sOptions)
            .(empty($sRepo) ? '' : ' '.$sRepo)
            .(empty($sRefspec) ? '' : ' '.$sRefspec)
        );

        return $result;
    }

    public function gitPush($sOptions=null, $sRepo=null, $sRefspec=null){
        $result = $this->exec('git push '
            .(empty($sOptions) ? '' : ' '.$sOptions)
            .(empty($sRepo) ? '' : ' '.$sRepo)
            .(empty($sRefspec) ? '' : ' '.$sRefspec)
        );

        return $result;
    }

    /**
     * @return string the raw result from git status
     */
    public function gitStatus(){
        $result = $this->exec('git status');
        return $result;
    }

}

One possibility is to use PHP's SSH library to perform those actions by connecting back to the web server?

Or I found this set of classes which allow you to you to clone and read other metadata over HTTP, but not push nor pull. However it could be a starting point if you're brave enough to extend them to do that. I can imagine it would be a lot of work to replicate these processes and keep them compliant with various server versions etc.

[UPDATED 23/03/2014, after receiving an upvote - thanks!]

I did get some way trying to implement the above (I was searching for an implementation, drew a blank so tried to write my own), and it was hard as I thought! I actually abandoned it as I found a simpler way to achieve this in a different architecture, but here's the class I wrote trying. It essentially works, but was brittle to the environmental variations I was working in (i.e. it doesn't cope very well with errors or problems).

It uses:

  1. herzult/php-ssh
  2. an ssh config file - a trick to simplify setting up authentication credentials in code

(Note - I had to quickly strip out a few details from the code to post it. So you'll need to fiddle about a bit to integrate it into your app/namespace etc.)

<?php
/**
 * @author: scipilot
 * @since: 31/12/2013
 */

/**
 * Class GitSSH allows you to perform Git functions over an SSH session.
 * i.e. you are using the command-line Git commands after SSHing to a host which has the Git client.
 *
 * You don't need to know about the SSH to use the class, other than the fact you will need access
 * to a server via SSH which has the Git client installed. Its likely this is the local web server.
 *
 * This was made because PHP has no good native Git client.
 *
 * Requires herzult/php-ssh
 *
 * Example php-ssh config file would be
 *
 * <code>
 *  Host localhost
 *  User git
 *  IdentityFile id_rsa
 *
 *  Host your.host.domain.com
 *  User whoever
 *  IdentityFile ~/.ssh/WhoeverGit
 *</code>
 */
class GitSSH {
    protected $config;
    protected $session;
    protected $sPath;
    /**
     * @var string
     */
    protected $sConfigPath = '~/.ssh/config';

    /**
     * Connects to the specified host, ready for further commands.
     *
     * @param string $sHost         Host (entry in the config file) to connect to.
     * @param string $sConfigPath Optional; config file path. Defaults to ~/.ssh/config,
     *                            which is probably inaccessible for web apps.
     */
    function __construct($sHost, $sConfigPath=null){
        \Log::info('New GitSSH '.$sHost.', '.$sConfigPath);
        if(isset($sConfigPath)) $this->sConfigPath = $sConfigPath;

        $this->config = new \Ssh\SshConfigFileConfiguration($this->sConfigPath, $sHost);
        $this->session = new \Ssh\Session($this->config, $this->config->getAuthentication());
    }

    public function __destruct() {
        $this->disconnect();
    }

    /**
     * Thanks to Steve Kamerman, as there isn't a native disconnect.
     */
    public function disconnect() {
        $this->exec('echo "EXITING" && exit;');
        $this->session = null;
    }

    /**
     * Run a command (in the current working directory set by cd)
     * @param $sCommand
     * @return string
     */
    protected function exec($sCommand) {
        //echo "\n".$sCommand."\n";
        $exec = $this->session->getExec();
        $result = $exec->run('cd '.$this->sPath.'; '.$sCommand);
        // todo: parse/scrape the result, return a Result object?
        return $result;
    }

    /**
     * CD to a folder. (This not an 'incremental' cd!)
     * Devnote: we don't really execute the cd now, it's appended to other commands. Each command seems to re-login?
     *
     * @param string $sPath Absolute filesystem path, or relative from user home
     */
    public function cd($sPath){
        $this->sPath = $sPath;

        // @todo this is useless! each command seems to run in a separate login?
        //$result = $this->exec('cd'); // /; ls');
        //return $result;
    }

    /**
     * @return string
     */
    public function ls(){
        $result = $this->exec('ls ');

        return $result;
    }

    public function gitAdd($sOptions=null, array $aFiles=null){
        $result = $this->exec('git add '
            .(empty($sOptions) ? '' : ' '.$sOptions)
            .(empty($aFiles) ? '' : ' '.implode(' ', $aFiles))
        );

        return $result;
    }

    public function gitClone($sRepo, $sBranch=null, $sTarget=null){
        \Log::info('GitSSH::clone '.$sRepo.', '.$sBranch.', '.$sTarget);
        $result = $this->exec('git clone '
            .(empty($sBranch) ? '' : ' --branch '.$sBranch)
            .' '.$sRepo
            .' '.$sTarget);

        return $result;
    }

    public function gitCommit($sMessage, $sOptions=null, array $aFiles=null){
        $result = $this->exec('git commit '
            .'-m "'.addcslashes($sMessage, '"').'"'
            .(empty($sOptions) ? '' : ' '.$sOptions)
            .(empty($aFiles) ? '' : ' '.implode(' ', $aFiles))
        );

        return $result;
    }

    public function gitPull($sOptions=null, $sRepo=null, $sRefspec=null){
        $result = $this->exec('git pull '
            .(empty($sOptions) ? '' : ' '.$sOptions)
            .(empty($sRepo) ? '' : ' '.$sRepo)
            .(empty($sRefspec) ? '' : ' '.$sRefspec)
        );

        return $result;
    }

    public function gitPush($sOptions=null, $sRepo=null, $sRefspec=null){
        $result = $this->exec('git push '
            .(empty($sOptions) ? '' : ' '.$sOptions)
            .(empty($sRepo) ? '' : ' '.$sRepo)
            .(empty($sRefspec) ? '' : ' '.$sRefspec)
        );

        return $result;
    }

    /**
     * @return string the raw result from git status
     */
    public function gitStatus(){
        $result = $this->exec('git status');
        return $result;
    }

}
三人与歌 2025-01-12 07:59:21

这看起来很有希望:http://gitphp.org(链接已损坏;请参阅 存档版本

我想这会为你做的。这是它的描述:

GitPHP 是 git 存储库的 Web 前端。它模仿标准 gitweb 的外观,但用 PHP 编写,并使用 Smarty 模板进行定制。它有一些额外功能,包括通过 GeSHi PHP 类和项目类别支持进行语法突出显示。它适用于标准 git 以及 Windows 上的 msysgit。

安装应该相当简单 - 只需在要安装的位置提取 tarball,将 config/gitphp.conf.php.example 复制到 config/gitphp.conf.php,然后将 conf 中的项目根目录设置为指向您的裸 git 存储库所在的目录,并让 templates_c 目录可由网络服务器写入(如果尚未写入)。
您可以查看 config/gitphp.conf.defaults.php 中的所有可用选项和默认值,如果您想覆盖默认值,请将选项复制到配置文件中。如果您想对项目进行更高级的控制,例如定义项目类别或从文本文件加载项目,您还可以将 config/projects.conf.php.example 复制到 config/projects.conf.php 并对其进行编辑。包含的自述文件中有更详细的说明。

注意:如果您要升级,现有的 gitphp.conf.php 不会被覆盖,但我建议检查 gitphp.conf.defaults.php 是否有可能已添加的新配置选项。

您可以查看此站点上运行的 Live Copy。

This looks promising: http://gitphp.org (broken link; see an archived version)

I think that will do it for you. Here is the description of it:

GitPHP is a web frontend for git repositories. It emulates the look of standard gitweb, but is written in PHP and makes use of Smarty templates for customization. It has a couple extras, including syntax highlighting through the GeSHi PHP class and project category support. It works with standard git as well as msysgit on Windows.

Setup should be fairly simple – just extract the tarball where you want to install it, copy config/gitphp.conf.php.example to config/gitphp.conf.php, and set the projectroot in the conf to point to your directory where your bare git repositories are, and make the templates_c directory writeable by the webserver if it’s not already.
You can look through all the available options and defaults in config/gitphp.conf.defaults.php, and copy an option into your config file if you want to override the default. You can also copy config/projects.conf.php.example to config/projects.conf.php and edit it if you want more advanced control over your projects, such as defining categories for projects or loading projects from a text file. More detailed instructions are in the included README.

Note: if you’re upgrading your existing gitphp.conf.php will not be overwritten, but I recommend checking gitphp.conf.defaults.php for new configuration options that may have been added.

You can view the live copy running on this site.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文