让SSH服务器当Git服务器 — 实战总结
基于实际踩坑经验,补充非标准端口、HEAD指向、裸仓库等常见问题的解决方案。
1. 环境准备
一台能远程SSH连接的服务器,多台客户端。客户端需要都能SSH连接这台服务器。
非标准端口场景(如22001)
SSH端口不是22时,推荐配置 SSH config,一劳永逸:
# 编辑 ~/.ssh/config,添加:
Host mygit
HostName 服务器IP
Port 22001
User 你的账号
之后用别名访问即可:
ssh mygit # 登录
git clone mygit:仓库名 # clone
SSH密钥认证(免密)
# 1. 本机生成密钥(已有则跳过)
ssh-keygen -t ed25519 -C "your_email@example.com"
# 2. 复制公钥到远程服务器
ssh-copy-id -p 22001 账号@ip
# 3. 测试免密登录
ssh -p 22001 账号@ip
配置后所有 Git 操作无需再输密码。
2. 远程服务器 — 创建裸仓库
# 创建裸仓库,推荐直接指定默认分支为 main
git init --bare --initial-branch=main hello-test
# 查看目录结构:含 HEAD hooks info objects refs 等
cd hello-test && ls -la
什么是裸仓库(bare)?
git init --bare创建的是没有工作区的仓库,本质上就是普通仓库的.git目录。因此在远程服务器上看不到提交的文件实体,文件存储在 Git 对象数据库中。其他客户端git clone后就能看到了。
验证裸仓库内容的方法:
git -C ~/hello-test log main # 查看 main 分支提交
git -C ~/hello-test branch # 查看所有分支
git -C ~/hello-test ls-tree --name-only main # 列出 main 分支的文件
3. 客户端 — 场景一:从零开始(先 clone 空仓库)
本地没有项目,从远程空仓库开始。
# 设置默认分支名为 main
git config --global init.defaultBranch main
# 标准端口:
git clone 账号@ip:hello-test
# 非标准端口(未配SSH config时,用完整URL):
git clone ssh://账号@ip:22001/~/hello-test
cd hello-test
echo "hello world" >> hello.txt
git add hello.txt
git commit -m "hello-world"
git push origin main
4. 客户端 — 场景二:本地已有代码(关联远程推送)
本地已有项目且已 commit 过代码,不需要 git clone,直接关联远程仓库。
# 标准端口:
git remote add origin 账号@ip:hello-test
# 非标准端口:
git remote add origin ssh://账号@ip:22001/~/hello-test
# 推送
git push -u origin main
如果本地分支名是 master:
# 方式A:直接推,映射到远程 main
git push -u origin master:main
# 方式B:先重命名本地分支
git branch -M main
git push -u origin main
5. 修复 HEAD 指向问题
git init --bare 创建的仓库,HEAD 默认指向 refs/heads/master。如果你推送的分支是 main,在远程执行 git log 会报错:
fatal: bad default revision 'HEAD'
修复
# 在远程服务器上,将 HEAD 指向 main
git -C ~/hello-test symbolic-ref HEAD refs/heads/main
预防
# 创建裸仓库时直接指定默认分支
git init --bare --initial-branch=main hello-test
6. 远程服务器查看日志
# 指定分支查看(不依赖 HEAD,最可靠)
git -C ~/hello-test log main
# 修复 HEAD 指向后可直接用
git -C ~/hello-test log
7. 其他客户端 clone
# 标准端口:
git clone 账号@ip:hello-test
# 非标准端口:
git clone ssh://账号@ip:22001/~/hello-test
cd hello-test && ls -la
cat hello.txt
流程总结
| 场景 | 远程操作 | 本地操作 |
|---|---|---|
| 全新开始 | git init --bare --initial-branch=main |
git clone → 写代码 → git push |
| 本地已有代码 | git init --bare --initial-branch=main |
git remote add → git push |
常见问题速查
| 问题 | 原因 | 解决 |
|---|---|---|
| push后远程看不到文件 | 裸仓库没有工作区,这是正常的 | git clone 到本地查看 |
fatal: bad default revision 'HEAD' |
HEAD指向master但推送的是main | git symbolic-ref HEAD refs/heads/main |
git push 显示 "up-to-date" 但远程没内容 |
可能push到了其他路径 | 检查 git remote -v,用绝对路径 |
| 端口2222无法连接 | Git简写不支持非标准端口 | 用 ssh://账号@ip:端口/路径 格式,或配SSH config |
| 每次push都要输密码 | 用了密码认证 | 配置SSH密钥认证 |