
Linux 安装 Git 服务器服务器: ecs-57c4-0004 (FlexusX 8vCPU/16GiB) |OS: Ubuntu 24.04 |Git: 2.43.0IP: 192.168.0.114 (内网) / 120.46.167.216 (公网) |日期: 2026-06-17目录Git 简介与托管平台对比Git 核心操作搭建 Git 服务器代码推送与多人协作验证1. Git 简介与托管平台对比1.1 版本控制演进集中式 (SVN): 分布式 (Git): [Server: repo] [Server: repo] | | | | | [ClientA][ClientB][ClientC] [ClientA: [ClientB: full-repo] full-repo] 离线不可提交 每个 clone 都是完整镜像 单点故障 历史丢失 即使服务器故障任意 clone 可恢复1.2 常见托管平台平台类型资源需求特点Bare Git SSH原生自建50MB零依赖最轻量。适合小团队Gitea轻量自建2GBGo 编写Web UI内置 CI/CDGogs轻量自建500MBGitea 前身安装包 30MBGitLab CE重型自建4GB完整 DevOps (CI/CD/Registry/K8s)GitoliteSSH 层10MBPerl 编写细粒度权限控制GitHubSaaS—全球最大PR/2FA/ActionsBitbucketSaaS—Atlassian 生态Jira 集成本次实验选用Bare Git SSH方案 — 纯命令行零依赖是理解 Git 服务端原理的最佳起点。1.3 Git 核心概念Working Directory (工作区) | git add ← 暂存变更 Staging Area (暂存区) | git commit ← 写入本地历史 Local Repo (本地仓库) | git push ← 同步到远程 Remote Repo (远程仓库) 三种状态: Modified → Staged → Committed1.4 环境信息$ git --version git version 2.43.0 $ which git /usr/bin/git $ hostname ecs-57c4-00042. Git 核心操作2.1 仓库初始化$mkdirmyprojectcdmyproject $gitinit Initialized empty Git repositoryin/tmp/myproject/.git/ $gitconfig user.emaildevlab.local$gitconfig user.nameDevelopergit init会在当前目录创建.git/隐藏目录包含所有版本控制元数据.git/ ├── HEAD → 指向当前分支 ├── config → 仓库配置 ├── description → 仓库描述 ├── hooks/ → 钩子脚本 ├── objects/ → 对象存储 (blob/tree/commit) └── refs/ → 分支和标签引用2.2 首次提交 (add commit)$cathello.pyEOF def greet(name): return fHello, {name}! EOF$gitaddhello.py# 添加到暂存区$gitcommit-mfeat: add greeting module[master(root-commit)9bd7460]feat:addgreeting module1filechanged,6insertions()create mode100644hello.pygit add将工作区变更加入暂存区。git commit将暂存区内容写入仓库生成 SHA-1 哈希作为版本 ID。$gitlog--oneline9bd7460 feat:addgreeting module2.3 修改追踪$gitdiff# 查看工作区 vs 暂存区差异diff--gita/hello.py b/hello.py --- a/hello.py b/hello.py -4,3 4,6 def greet(name):if__name____main__:print(greet(World)) def farewell(name): returnfGoodbye, {name}!$gitaddhello.pygitcommit-mfeat: add farewell function[master 5ca3894]feat:addfarewellfunction1filechanged,3insertions()2.4 分支操作$gitbranch feature-calc# 创建分支$gitcheckout feature-calc# 切换分支Switched to branchfeature-calc$catcalc.pyEOF def add(a, b): return a b def mul(a, b): return a * b EOF$gitaddcalc.pygitcommit-mfeat: add calculator module[feature-calc 2e49d39]feat:addcalculator module $gitlog--oneline--all--graph* 2e49d39 feat:addcalculator module ← feature-calc * 5ca3894 feat:addfarewellfunction← master * 9bd7460 feat:addgreeting module2.5 合并分支 (merge)$gitcheckout master $gitmerge feature-calc-mmerge: integrate calculatorUpdating 5ca3894..1d4036d Fast-forward .gitignore|4 README.md|2 calc.py|23files changed,8insertions()$gitlog--oneline--all--graph* 1d4036d chore:add.gitignore and README * 2e49d39 feat:addcalculator module * 5ca3894 feat:addfarewellfunction* 9bd7460 feat:addgreeting moduleFast-forward: 当 master 上没有新提交时Git 直接移动指针而不是创建合并提交保持历史线性。2.6 .gitignore$cat.gitignoreEOF __pycache__/ *.pyc .env *.log EOF3. 搭建 Git 服务器3.1 架构概览┌──────────────────────────────────────────────────────┐ │ Git Server (192.168.0.114) │ │ │ │ /home/git/ │ │ ├── .ssh/authorized_keys ← 客户端公钥 │ │ └── repositories/ │ │ └── myproject.git/ ← 裸仓库 (bare repo) │ │ ├── HEAD │ │ ├── config │ │ ├── objects/ ← blob/tree/commit │ │ └── refs/ ← branches/tags │ │ │ │ SSH (port 22) │ │ ↑ git-shell (只允许 git 命令) │ │ │ │ └───┼──────────────────────────────────────────────────┘ │ │ git clone git192.168.0.114:/home/git/repositories/myproject.git │ ┌───┴──────────────┐ ┌──────────────────┐ │ Alice (客户端) │ │ Bob (客户端) │ │ clone → push │ │ clone → push │ └──────────────────┘ └──────────────────┘3.2 创建专用 git 用户$sudouseradd-m-s/usr/bin/git-shellgit$idgituid1003(git)gid1003(git)groups1003(git)$grepgit/etc/passwd git:x:1003:1003::/home/git:/usr/bin/git-shellgit-shell: 限制 Shell只允许执行git-receive-pack、git-upload-pack、git-upload-archive三个命令。禁止交互式登录保障安全。$whichgit-shell /usr/bin/git-shell3.3 创建裸仓库 (–bare)$sudomkdir-p/home/git/repositories $sudochown-Rgit:git /home/git/repositories $cd/home/git/repositories $sudo-ugitgitinit--baremyproject.git Initialized empty Git repositoryin/home/git/repositories/myproject.git/裸仓库(--bare) 没有工作目录只包含.git元数据专用于服务端共享。3.4 裸仓库内部结构$ls-la/home/git/repositories/myproject.git/ total 32K drwxrwxr-x2gitgit4.0K branches/# 废弃现代 Git 不用-rw-rw-r--1gitgit66config# 仓库配置-rw-rw-r--1gitgit73description# 仓库描述 (GitWeb 用)-rw-rw-r--1gitgit23HEAD# 当前活动分支 → ref: refs/heads/masterdrwxrwxr-x2gitgit4.0K hooks/# 钩子 (pre-receive/post-receive等)drwxrwxr-x2gitgit4.0K info/# 附加信息 (exclude/grafts)drwxrwxr-x4gitgit4.0K objects/# 核心! 所有 Git 对象drwxrwxr-x4gitgit4.0K refs/# 分支/tag 指针$cat/home/git/repositories/myproject.git/HEAD ref: refs/heads/masterobjects/ 目录是最核心的存储objects/ ├── 68/ ← 对象按哈希前 2 位分组 │ └── 9a53c... ← blob (文件内容) ├── 37/ ← 压缩存储 │ └── c45b3... ← commit (提交元数据) ├── info/ └── pack/ ← 打包优化3.5 SSH 密钥认证配置# 客户端生成密钥对 $ ssh-keygen-ted25519-Cdevlab.local# 生成: ~/.ssh/id_ed25519 (私钥) ~/.ssh/id_ed25519.pub (公钥)# 服务端: 添加公钥 $sudomkdir-p/home/git/.ssh $cat/tmp/user_key.pub/home/git/.ssh/authorized_keys $sudochown-Rgit:git /home/git/.ssh $sudochmod700/home/git/.ssh $sudochmod600/home/git/.ssh/authorized_keys $ls-la/home/git/.ssh/ total8drwx------2gitgit4096Jun1723:11.drwxr-x---4gitgit4096Jun1723:11..-rw-------1gitgit574Jun1723:11 authorized_keys ←1条公钥3.6 客户端远程添加# 基本格式gitremoteaddorigin gitserver:/home/git/repositories/myproject.git# 使用 ~/.ssh/config 别名 (推荐)$cat~/.ssh/configEOF Host git-server HostName 192.168.0.114 User git IdentityFile ~/.ssh/id_rsa_git StrictHostKeyChecking no EOF# 简化后gitremoteaddorigin git-server:myproject.git4. 代码推送与多人协作验证4.1 Alice 克隆仓库$GIT_SSH_COMMANDssh -i ~/.ssh/id_rsa_git\gitclone git192.168.0.114:/home/git/repositories/myproject.git alice Cloning intoalice... $cdalicels-la*.py -rw-r--r--1root root56Jun1723:12 calc.py -rw-r--r--1root root175Jun1723:12 hello.py4.2 Alice 提交新功能$catapp.pyEOF from hello import greet from calc import add, mul def main(): print(greet(Team)) print(f2 3 {add(2, 3)}) print(f4 * 5 {mul(4, 5)}) EOF$gitaddapp.pygitcommit-mfeat: add main entry point[master 37c45b3]feat:addmain entry point1filechanged,11insertions()$GIT_SSH_COMMANDssh -i ~/.ssh/id_rsa_gitgitpush origin master To192.168.0.114:/home/git/repositories/myproject.git 689a53c..37c45b3 master -master4.3 Bob 克隆并贡献$GIT_SSH_COMMANDssh -i ~/.ssh/id_rsa_git\gitclone git192.168.0.114:/home/git/repositories/myproject.git bob Cloning intobob... $catutils.pyEOF import time def timestamp(): return time.strftime(%Y-%m-%d %H:%M:%S) def log(msg): print(f[{timestamp()}] {msg}) EOF$gitaddutils.pygitcommit-mfeat: add logging utility[master 117634a]feat:addlogging utility $GIT_SSH_COMMANDssh -i ~/.ssh/id_rsa_gitgitpush origin master To192.168.0.114:/home/git/repositories/myproject.git 37c45b3..117634a master -master4.4 Alice 拉取 Bob 的更改$cdalice $GIT_SSH_COMMANDssh -i ~/.ssh/id_rsa_gitgitpull origin master From192.168.0.114:/home/git/repositories/myproject * branch master -FETCH_HEAD Updating 37c45b3..117634a Fast-forward utils.py|71filechanged,7insertions()$gitlog--oneline--all--graph* 117634a feat:addlogging utility ← Bob * 37c45b3 feat:addmain entry point ← Alice * 689a53c feat: initial project structure $ls-la*.py -rw-r--r--1root root218app.py -rw-r--r--1root root56calc.py -rw-r--r--1root root175hello.py -rw-r--r--1root root127utils.py ← Bob 的文件已同步4.5 服务器端验证# 查看提交历史$sudo-ugitgit--git-dir/home/git/repositories/myproject.git log--oneline--all117634a feat:addlogging utility 37c45b3 feat:addmain entry point 689a53c feat: initial project structure# 查看分支$sudo-ugitgit--git-dir/home/git/repositories/myproject.git branch-a* master# 查看所有文件$sudo-ugitgit--git-dir/home/git/repositories/myproject.git ls-tree --name-only HEAD .gitignore README.md app.py calc.py hello.py utils.py# 对象统计$sudo-ugitgit--git-dir/home/git/repositories/myproject.git count-objects-vHcount:12←12个 Git 对象 size:48.00KiB ← 原始大小# 仓库总大小$du-sh/home/git/repositories/myproject.git/ 220K /home/git/repositories/myproject.git/4.6 协作流程总结Alice Git Server Bob │ │ │ │── clone ─────────────│ │ │── repo ──────────────│ │ │ │ │ │ [编辑 app.py] │ │ │── push (37c45b3) ────│ │ │ │ │ │ │── clone ──────────────│ │ │── repo ───────────────│ │ │ [编辑 utils.py] │ │ │── push (117634a) ─────│ │ │ │ │── pull (117634a) ────│ │ │ [Fast-forward] │ │ │ utils.py 同步 │ │5. 进阶话题5.1 服务端钩子 (Hooks)# post-receive: push 后自动部署$cat/home/git/repositories/myproject.git/hooks/post-receiveEOF #!/bin/bash # 推送到生产目录 DEPLOY_DIR/var/www/myproject while read oldrev newrev ref; do if [ $ref refs/heads/master ]; then git --work-tree$DEPLOY_DIR checkout -f master systemctl reload myproject # 重启服务 echo Deployed $newrev to $DEPLOY_DIR fi done EOF$chmodx /home/git/repositories/myproject.git/hooks/post-receive5.2 权限控制# 方案1: 文件系统权限 (最简单)chmod750/home/git/repositories/private-project.git/# 方案2: Gitolite (细粒度)# repo myproject# RW alice# R bob# - interns# 方案3: GitLab CE (Web UI 管理)# 项目 → Settings → Members → 选择角色5.3 安全加固# 1. SSH 仅允许密钥登录$grep-EPasswordAuthentication|PubkeyAuthentication/etc/ssh/sshd_config PubkeyAuthenticationyesPasswordAuthentication no# 2. 定期清理已离职开发者密钥$sudovim/home/git/.ssh/authorized_keys# 3. 审计 Git 操作日志$sudogrepgit/var/log/auth.log|tail-55.4 仓库备份# 方案1: 定期 rsync$rsync-az/home/git/repositories/ backup-server:/git-backup/# 方案2: git bundle (单文件打包)$cd/home/git/repositories/myproject.git $gitbundle create myproject.bundle--all# 方案3: 从任意 clone 恢复$gitclone--baregitserver:/path/to/repo.git6. 故障排查症状原因解决Permission denied (publickey)密钥未添加或权限不对chmod 600 ~/.ssh/id_rsa; 检查 authorized_keysfatal: does not appear to be a git repository路径错误确认裸仓库路径ls /home/git/repositories/remote: error: insufficient permissiongit 用户无写权限chown -R git:git /home/git/repositories/hint: Updates were rejected远端有更新的提交git pull --rebase再 pushdetected dubious ownershipgit 安全策略 (CVE)git config --global --add safe.directory /pathPermission denied (publickey,password)SSH 密钥未配置或不对重新 ssh-copy-id 或手动添加公钥fatal: Not a valid object name master裸仓库为空首次需要git push -u origin master7. 命令速查表操作命令创建裸仓库git init --bare /path/to/repo.git克隆仓库git clone gitserver:/path/to/repo.git添加文件git add file提交变更git commit -m msg推送到远程git push origin master拉取更新git pull origin master查看历史git log --oneline --graph --all查看差异git diff创建分支git branch feature-x切换分支git checkout feature-x合并分支git merge feature-x查看远程git remote -v添加远程git remote add origin url查看状态git status撤销暂存git restore --staged file查看提交详情git show HEAD创建标签git tag v1.0.0查看文件列表git ls-tree --name-only HEAD文档版本: v1.0 |创建日期: 2026-06-17服务器: ecs-57c4-0004 (FlexusX 8vCPU/16GiB)