6 版本控制与协作
7 版本控制与协作
在科学研究中,代码和数据的版本管理是确保可重复性的关键环节。本章介绍 Git 版本控制系统和 GitHub 协作平台的使用方法。
7.1 为什么需要版本控制?
你是否遇到过这样的情况?
论文_v1.docx
论文_v2.docx
论文_v2_导师修改.docx
论文_v3_最终版.docx
论文_v3_最终版_真的最终版.docx
论文_v3_最终版_打死不改了.docx
版本控制系统(Version Control System, VCS)就是为了解决这个问题。Git 是目前最流行的版本控制工具,它能:
- 记录文件的每一次修改历史
- 随时回退到任意历史版本
- 多人协作时自动合并修改
- 追踪每个人的贡献
7.2 Git 基本概念
7.2.1 仓库(Repository)
仓库是 Git 管理的项目文件夹。分为:
- 本地仓库:在你电脑上的项目文件夹
- 远程仓库:托管在 GitHub 等平台上的副本
7.2.2 工作区、暂存区、版本库
工作区(Working Directory)
↓ git add
暂存区(Staging Area)
↓ git commit
版本库(Repository)
↓ git push
远程仓库(Remote)
- 工作区:你正在编辑的文件
- 暂存区:准备提交的文件(
git add后) - 版本库:已提交的历史记录(
git commit后)
7.3 首次使用 Git:初始配置
安装 Git 后,第一件事是告诉 Git 你是谁。这些信息会记录在每次提交中:
# 设置用户名和邮箱(只需执行一次)
git config --global user.name "你的名字"
git config --global user.email "你的邮箱@example.com"
# 验证设置
git config --list
Warning邮箱要和 GitHub 账号一致
user.email 应该填你注册 GitHub 时使用的邮箱,否则 GitHub 无法正确关联你的提交记录。
7.4 常用 Git 命令
7.4.1 初始化与克隆
# 在当前文件夹初始化 Git 仓库
git init
# 克隆远程仓库到本地
git clone https://github.com/username/repo-name.git7.4.2 日常工作流
# 查看当前状态(哪些文件被修改了)
git status
# 将修改添加到暂存区
git add filename.R # 添加单个文件
git add . # 添加所有修改
# 提交到版本库(附带说明信息)
git commit -m "添加数据清洗脚本"
# 推送到远程仓库
git push origin main
# 从远程仓库拉取最新代码
git pull origin main7.4.3 查看历史
# 查看提交历史
git log --oneline
# 查看某个文件的修改历史
git log --oneline -- analysis.R
# 查看具体修改内容
git diff
Tip写好提交信息
好的提交信息应该简洁明了,说明”做了什么”:
- ✅
添加土壤pH数据清洗脚本 - ✅
修复物种名称拼写错误 - ✅
更新图表配色方案 - ❌
修改了一些东西 - ❌
update - ❌
...
7.5 GitHub 协作
7.5.1 Fork 与 Pull Request
在团队协作中,常用的工作流程是:
- Fork:将别人的仓库复制一份到自己的 GitHub 账号
- Clone:将 Fork 的仓库克隆到本地
- 修改:在本地进行修改并提交
- Push:推送到自己的 GitHub 仓库
- Pull Request(PR):向原仓库发起合并请求
# 1. Fork 后克隆自己的仓库(替换为你的 GitHub 用户名)
git clone https://github.com/your-username/repo-name.git
# 2. 创建新分支进行修改
git checkout -b feature/add-analysis
# 3. 修改文件并提交
git add .
git commit -m "添加多样性分析脚本"
# 4. 推送到自己的仓库
git push origin feature/add-analysis
# 5. 在 GitHub 网页上创建 Pull Request7.5.2 Issue
Issue 是 GitHub 上的问题追踪工具,可以用来:
- 报告 Bug
- 提出新功能需求
- 讨论项目方向
- 记录待办事项
7.6 在 RStudio 中使用 Git
RStudio 内置了 Git 图形界面,不需要记命令行:
7.6.1 创建 Git 项目
- File → New Project → Version Control → Git
- 输入远程仓库 URL
- 选择本地存放路径
- 点击 Create Project
7.6.2 日常操作
RStudio 右上角的 Git 面板提供了常用操作:
- 查看修改:Git 面板会显示所有被修改的文件
- 暂存文件:勾选文件前的复选框(等同于
git add) - 提交:点击 Commit 按钮,输入提交信息(等同于
git commit) - 推送/拉取:点击 Push/Pull 按钮(等同于
git push/git pull)
NoteRStudio 中的 Git 快捷键
Ctrl + Alt + M:打开 Commit 窗口Ctrl + Alt + D:查看 Diff(文件差异)
7.7 常见问题与错误处理
7.7.1 合并冲突(Merge Conflict)
当两个人同时修改了同一个文件的同一部分,Git 无法自动合并,就会产生合并冲突。这是初学者最常遇到的问题。
执行 git pull 时如果出现冲突,Git 会在文件中标记冲突位置:
<<<<<<< HEAD
# 你的修改
mean_height <- mean(data$height, na.rm = TRUE)
=======
# 队友的修改
mean_height <- median(data$height, na.rm = TRUE)
>>>>>>> origin/main
解决步骤:
- 打开冲突文件,找到
<<<<<<<、=======、>>>>>>>标记 - 决定保留哪个版本(或合并两者),删除所有标记符号
- 保存文件后提交:
git add filename.R
git commit -m "解决合并冲突:统一使用均值计算株高"
Tip预防冲突的好习惯
- 每次开始工作前先
git pull拉取最新代码 - 团队成员尽量编辑不同的文件
- 频繁提交、频繁推送,减少冲突范围
7.7.2 常见错误及解决方法
推送被拒绝(push rejected)
! [rejected] main -> main (fetch first)
原因:远程仓库有你本地没有的新提交。先拉取再推送:
git pull origin main
# 如果有冲突,解决冲突后再推送
git push origin main误提交了不该提交的文件
# 从暂存区移除(文件本身不删除)
git reset HEAD filename.csv
# 如果已经 commit 了,撤销最近一次提交(保留修改)
git reset --soft HEAD~1修改了文件但想恢复原样
# 丢弃工作区的修改,恢复到上次提交的状态
git restore filename.R
Warning
git restore 不可撤销
git restore 会丢弃你未提交的修改,且无法恢复。使用前请确认你确实不需要这些修改。
7.8 .gitignore 文件
有些文件不应该被 Git 追踪(如大型数据文件、临时文件、密钥等)。在项目根目录创建 .gitignore 文件:
# R 临时文件
.Rhistory
.RData
.Rproj.user/
# 数据文件(太大不适合放 Git)
data/raw/*.csv
data/raw/*.xlsx
# 系统文件
.DS_Store
Thumbs.db
# 编译产物
docs/
_freeze/
Warning不要把敏感信息提交到 Git
API 密钥、密码、个人隐私数据等绝对不能提交到 Git 仓库,尤其是公开仓库。一旦提交,即使删除文件,历史记录中仍然可以找到。
7.9 项目文件组织规范
一个规范的数据分析项目应该有清晰的文件结构:
my-project/
├── README.md # 项目说明
├── .gitignore # Git 忽略规则
├── data/
│ ├── raw/ # 原始数据(不修改)
│ └── processed/ # 处理后的数据
├── scripts/
│ ├── 01-clean.R # 数据清洗
│ ├── 02-analyze.R # 数据分析
│ └── 03-visualize.R # 数据可视化
├── output/
│ ├── figures/ # 图表
│ └── tables/ # 表格
└── docs/
└── report.qmd # 分析报告
关键原则:
- 原始数据只读:
data/raw/中的文件永远不修改 - 脚本有编号:按执行顺序编号,方便他人复现
- 输出可重建:
output/中的所有文件都能通过运行脚本重新生成 - 有 README:说明项目目的、数据来源、运行方法
7.10 实践:分组创建项目仓库
按照以下步骤完成本章实践:
- 在 GitHub 上创建一个新仓库,命名为
ecology-data-project - 添加 README.md 和 .gitignore(选择 R 模板)
- 克隆到本地(使用 RStudio)
- 按照上面的规范创建文件夹结构
- 添加一个简单的 R 脚本(如读取 iris 数据并保存描述性统计)
- 提交并推送到 GitHub
- 邀请组员作为 Collaborator
- 组员各自克隆仓库,添加自己的分析脚本,提交推送
7.11 课后练习
- 完成 Git 初始配置(
user.name和user.email) - 在 GitHub 上创建个人项目仓库,包含完整的文件夹结构
- 练习
git add→git commit→git push的完整流程 - 查看
git log确认提交历史 - 创建
.gitignore文件,排除不需要追踪的文件 - 尝试在 RStudio 中使用 Git 面板完成一次提交和推送
- (进阶)与同学协作制造一次合并冲突,练习解决冲突的流程