跳转至

30 - Git 与 GitHub 项目管理

前提条件

  • 已完成自动化部署与镜像管理章节(Ansible / Packer 流程已建立)
  • 本章操作以 ops 普通用户执行,不使用 root 进行 Git 日常操作
  • 系统运行在 Debian 12 Bookworm
  • 需要 GitHub 账号(或自建 Gitea 实例)
  • SSH 密钥已生成(第 8 章)

全局参数

主机名 linuxdc,IP 192.168.1.100/24,SSH 端口 2222,运维用户 ops

Git 操作使用 ops 用户

Git 相关操作应以普通用户 ops 身份执行,不使用 root 账户进行日常代码管理。root 账户的提交信息会暴露服务器 root 账户的存在,且不符合最小权限原则。

详细步骤

以下所有命令以 ops 用户执行:

su - ops

1. 安装 Git 并全局配置

# 安装(root 执行)
apt update && apt install -y git

# 以下配置由 ops 用户执行
git config --global user.name  "Ops User"
git config --global user.email "ops@linuxdc.local"
git config --global core.editor "vim"
git config --global init.defaultBranch main
git config --global pull.rebase false     # merge 策略(推荐明确设置)

# 验证配置
git config --list

2. 创建本地仓库与基础操作

mkdir ~/my-project && cd ~/my-project
git init

echo "# My Debian Ops Project" > README.md
git add README.md
git commit -m "init: add README"

# 查看状态与历史
git status
git log --oneline --graph --all

3. 配置 GitHub SSH 认证

将已有公钥添加到 GitHub(Settings → SSH and GPG keys → New SSH key):

cat ~/.ssh/id_ed25519.pub
# 复制输出内容,粘贴到 GitHub SSH Keys 页面

测试 SSH 连接:

ssh -T git@github.com
# 成功输出:Hi <username>! You've successfully authenticated, but GitHub does not provide shell access.

4. 关联远程仓库并推送

在 GitHub 创建新仓库(不要勾选"Initialize this repository"):

git remote add origin git@github.com:<your-username>/my-project.git
git branch -M main
git push -u origin main

5. 日常工作流(功能分支模型)

分支命名约定:

分支类型 命名格式 说明
主分支 main 生产代码,只合并经过 Review 的代码
功能分支 feature/<描述> 新功能开发
修复分支 fix/<描述> bug 修复
紧急修复 hotfix/<描述> 生产紧急修复
发布分支 release/<版本> 发布前的最终测试

功能开发示例:

# 从 main 创建功能分支
git checkout -b feature/add-logrotate-config

# 开发并提交
vim logrotate/nginx.conf
git add logrotate/nginx.conf
git commit -m "feat: add nginx logrotate config (rotate 14, compress)"

# 推送到远程
git push origin feature/add-logrotate-config

在 GitHub 创建 Pull Request,经过 Review 后合并到 main

6. 常用运维 Git 技巧

.gitignore 配置(运维仓库推荐):

vim .gitignore
# 日志文件
*.log
logs/

# 备份目录
/backup/

# 敏感文件(绝不提交)
*.key
*.pem
*credentials*
vault-password*
.env

# OS 临时文件
.DS_Store
Thumbs.db

撤销操作:

场景 命令 说明
撤销工作区修改 git restore <file> 丢弃未暂存的修改
取消暂存 git restore --staged <file> 从暂存区移出,保留工作区
安全撤销已推送提交 git revert HEAD 新建反向提交,保留历史
危险:彻底丢弃本地提交 git reset --hard HEAD~1 不可推送到共享分支

标签管理(版本标记):

# 创建带注释的标签
git tag -a v1.0.0 -m "Release v1.0.0: initial stable deployment"

# 推送标签到远程
git push origin v1.0.0

# 推送所有标签
git push origin --tags

# 列出所有标签
git tag -l

查看文件变更历史:

git log --follow -p -- playbooks/install-nginx.yml
git blame playbooks/install-nginx.yml

7. 仓库目录结构建议(运维项目)

debian-ops/
├── playbooks/          # Ansible playbooks
├── roles/              # Ansible roles
├── inventory/          # Ansible inventory
├── group_vars/         # 变量文件(secrets 用 vault 加密)
├── packer/             # Packer 模板
├── scripts/            # Shell 脚本
├── docs/               # 运维文档(Markdown)
├── .gitignore
└── README.md

8. GitHub 项目管理建议

  • 分支保护:Settings → Branches → Add protection rule → 对 main 分支启用 Require pull request reviews
  • Issues:用于跟踪任务、bug、待办项,关联 Pull Request(Closes #123
  • Actions:CI/CD 自动化(语法检查、ansible-lint、packer validate),在 Push 时自动触发

实践任务

  1. 安装 Git,完成全局配置,创建本地仓库 my-debian-ops,提交 README.md 并推送到 GitHub
  2. 配置 SSH 密钥认证,验证 ssh -T git@github.com 成功,测试无密码推送
  3. 创建 feature/add-logrotate 分支,添加 logrotate 配置文件,提交并推送,在 GitHub 创建 Pull Request
  4. 在本地修改 README.md,用 git revert 撤销最新提交,观察提交历史的变化

自测问题

1. git config --global init.defaultBranch main 的作用是什么?

Git 2.28 前,git init 创建的默认分支名为 master。该配置将新仓库的默认初始分支名改为 main,与 GitHub 等平台的当前默认值保持一致,避免本地 master 与远程 main 不匹配导致推送时需要额外的 git branch -M main 操作。这是全局配置,对当前用户之后创建的所有新仓库生效。

2. SSH 密钥认证相比 HTTPS 的主要优势是什么?

HTTPS 认证需要每次输入用户名和 Personal Access Token(GitHub 已停止支持账号密码),即使配置了 credential helper 本地缓存,令牌仍以明文形式存储在文件中。SSH 密钥认证使用非对称加密,私钥从不离开本地,服务端只存储公钥;可以为私钥设置 passphrase 并配合 ssh-agent 实现安全的免密操作;一个密钥对可用于多个 Git 服务(GitHub、GitLab、Gitea);密钥可按设备管理,单独吊销而不影响其他设备。

3. git revertgit reset 的区别是什么?什么时候用哪个?

git revert <commit> 创建一个新提交来撤销目标提交的内容,保留完整提交历史,适合已推送到共享分支(main)的提交——其他人拉取后不会出现历史分歧。git reset --hard <commit> 将 HEAD 和工作区直接回退到目标提交,丢弃其后的所有提交,如果已推送则需要 git push --force,会破坏其他人的本地仓库。原则:已推送的共享提交用 revert;仅本地未推送的提交可用 reset

4. 为什么生产环境中建议保护 main 分支并要求 Pull Request 审核?

直接向 main 推送跳过了代码审查和 CI 检查,一个误操作(错误的 Ansible playbook、删除生产配置)可能直接影响所有从 main 部署的环境。分支保护规则强制所有变更通过 Pull Request 流程:至少一名审核者 Review 代码;CI 检查(ansible-lintpacker validateshellcheck)通过后才能合并;所有变更有完整的讨论记录和审批轨迹,满足合规和审计要求。这是将"四眼原则"落实到代码管理层面的标准实践。

总结

Git 是运维工作中版本控制、协作、审计的核心工具。以 ops 用户管理 Git 仓库,将所有脚本、Ansible playbook、Packer 模板、运维文档纳入版本控制,是实现"基础设施即代码"可追溯性的基础。结合 Pull Request + CI 自动检查 + 分支保护,形成安全可靠的配置变更管控流程。