git init --bare 创建的仓库不能直接 push 是因为它是纯仓库,无工作区,无法自动更新文件;需配合 post-receive 钩子与 git_work_tree 指定目标路径实现自动部署。

git init --bare 创建的仓库为什么不能直接 push?
因为 git init --bare 生成的是纯仓库(no working directory),它只含 .git 内容,没有工作区,所以远程端不能执行 git checkout 或触发钩子自动更新文件。如果你希望 push 后代码自动出现在服务器目录里(比如 Web 根目录),必须配合 post-receive 钩子 + git --work-tree 指定目标路径。
常见错误现象:git push origin main 成功但服务器上看不到文件;或者报错 remote: error: refusing to update checked out branch(Git 2.15+ 默认禁止推送到已检出分支)。
- 解决方法:在 bare 仓库的
hooks/post-receive里写:
#!/bin/bash GIT_WORK_TREE=/var/www/myapp git checkout -f
- 注意给钩子加可执行权限:
chmod +x hooks/post-receive -
GIT_WORK_TREE路径必须存在且 git 用户有写权限 - 别用
git pull替代git checkout -f—— bare 仓库没工作区,pull 会失败
用 ssh 协议时,用户权限和路径怎么配才不踩坑?
Git 本身不管理用户认证,全靠 SSH 层控制。最稳妥的做法是**为 Git 单独建系统用户**,而不是用 root 或你的个人账户。
- 创建专用用户:
sudo adduser --shell /usr/bin/git-shell --disabled-password git(git-shell是受限 shell,防任意命令执行) - 把公钥放进
/home/git/.ssh/authorized_keys,每行开头加command="git-shell -c \"${SSH_ORIGINAL_COMMAND}\""限制仅允许 git 命令 - 仓库路径建议统一放在
/home/git/repo/下,所有 bare 仓库归该用户所有:sudo chown -R git:git /home/git/repo - 客户端 push 地址写成:
git@your-server:/home/git/repo/project.git,不要省略绝对路径
容易踩的坑:用个人账户配 key 后,仓库属主是你的用户,但 git 进程以 git 用户运行,导致权限拒绝;或者没设 git-shell,SSH 登录后能执行任意命令,有安全风险。
抓取指定 GitHub用户的 Stars 项目,生成标准化中文 Markdown 报告。用户提及「分析 GitHub stars」「导出收藏项目」「汇总 GitHub 星标」「生成 stars 报告」或粘贴含 ?tab=stars 的链接时触发。执行通过 bash...
HTTP 协议部署要不要用 Apache/Nginx?
要,但只推荐用作反向代理或基础认证层,**别让 Web 服务器直接跑 Git 服务**。Git 自带的 git-http-backend 是 CGI 程序,配置复杂、性能差、难调试。
- 更现实的选择:用 Nginx 反代到
git daemon(仅读)或gitea/gitlab-ce(读写+界面) - 如果坚持原生 HTTP 写入,必须配好
htpasswd+git-http-backend+SetEnv,且确保POST请求能穿透 CGI 层——Nginx 默认不转发 POST 到 CGI,容易卡在 405 或空响应 - HTTPS 必须配证书,否则
git clone https://...会因 SSL 验证失败中断(除非手动关验证,不推荐)
实际项目中,80% 的私有仓需求用 SSH 就够了;HTTP 主要用于开放只读、或集成 CI/CD 的 webhook 回调,这时候用 Gitea 提供的 API 更稳。
clone 时提示 fatal: Could not read from remote repository 是什么情况?
这几乎全是权限或路径问题,不是 Git 本身故障。先确认三件事:
- SSH 能连上吗?运行
ssh -T git@your-server—— 如果卡住或报Permission denied,说明密钥没配对或authorized_keys权限不对(应为 600) - 仓库路径存在吗?登录服务器执行
ls -l /home/git/repo/project.git,看属主是不是git,有没有objects/目录 - 客户端 URL 写对了吗?
git@server:path中的path是服务器上的绝对路径;如果写成git@server:repo/project.git(相对路径),SSH 会从/home/git/下找,但实际可能放在/opt/git/
一个典型漏点:服务器防火墙开了,但只放行了 22 端口,忘了 git daemon 默认走 9418 —— 这时候 clone http:// 或 git:// 都会超时,但错误信息还是 “Could not read”,容易误判。










