跳转至

让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 addgit 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密钥认证

参考资料