基本上,我想在远程服务器上即时设置一个存储库。通常,必须在远程服务器上初始化存储库,然后init --bare
才能从另一台设备推送提交。有什么方法可以规避这个问题吗?
理想情况下,我希望实现以下两点:
- 保持客户端不变,即除了 之外不需要其他设置
git remote add ...
。 - 使用 SSH 作为传输协议。
我目前想到的是:
忽略 SSH 需求。通过 HTTPS 推送,我可以托管一个 HTTPS 服务器,该服务器在接受推送之前初始化不存在的存储库。
更改服务器端的 git 功能,劫持推送命令(在 git-shell 中调用?)。我没有找到有关通过 SSH 推送时服务器端发生的情况的文档,因此我无法进一步研究此可能的解决方案。
与 #2 相关,我可以实现一个在远程运行的 SSH 服务器,在运行其他命令之前初始化不存在的存储库。但与 #2 一样,我找不到有关推送管道的文档。
澄清:
我可以推送到尚未初始化存储库的远程吗?我是否可以充分检测传入的推送,并在继续之前初始化存储库?
答案1
最终的解决方案基于#2:
更改服务器端的 git 功能,劫持推送命令(在 git-shell 中调用?)。我没有找到有关通过 SSH 推送时服务器端发生的情况的文档,因此我无法进一步研究此可能的解决方案。
我发现了一个“kamalmarhubi” 的文章这解释了git push
设置使用 SSH 时执行的操作。
解决方案
设置-服务器端
添加一个叫做git
:
sudo useradd -m git
请注意,遗憾的是用户无法使用 git-shell,因为 shell 在内部处理必要的命令。
创建.ssh
目录
mkdir .ssh
创建authorized_keys
文件
touch .ssh/authorized_keys
将您要使用的任何公钥作为一行添加到authorized_keys
文件中。
添加以下内容在之上用户的.bashrc
文件:
function git-receive-pack() {
if [ ! -d $1 ]; then
mkdir -p $1 && cd $1 && git init --quiet --bare && command git-receive-pack $@
fi
}
设置-客户端
在任何 git 存储库中执行以下操作:
git add remote origin git@server:directory
其中server
,服务器的 IP 或名称以及directory
存储库的路径(通常相对于 git 用户的主目录/home/git/
)。
用法
从客户端推送代码
像往常一样推送,服务已经帮您初始化存储库了!
怎么运行的
每当 Git 通过 SSH 推送时,它都会调用,即在远程ssh git@server git-receive-pack directory
运行。当使用 git-shell 时,命令在内部处理。当使用常规 shell(bash)时,该命令将作为任何其他 bash 命令处理。这意味着我们可以覆盖命令的工作方式,我们可以通过在 中定义自己的命令来实现。定义需要位于文件的顶部,因为如果它在非交互式 shell(如 Git)中运行,通常会中止执行。我们定义的命令会检查目标存储库是否已存在,如果不存在,它会将其初始化为裸存储库(按照 Git 标准),然后再运行原始存储库,由原始存储库负责实际推送。git-receive-pack directory
git-receive-pack
.bashrc
.bashrc
git-receive-pack