English

Collaboration requires both a record of changes and a way to judge their combined effect. Version control records versions and their relationships. Code review examines whether a proposed change solves the intended problem and fits the surrounding system. Neither mechanism alone establishes correctness.

The unit of collaboration is a change that someone else can understand: what behavior changes, why it changes, and what evidence supports it. A clear description and a focused diff make that judgment easier; a successful merge only shows that the version-control operation completed.

Prerequisites and connections: Programming (§2.1), code reading (§8.3), and writing code (§8.4). Software process (§7.3) places review and integration in the delivery workflow.

The Shape of the Skill: Coordinating Parallel Work and Shared Judgment

Version-control systems developed different ways to coordinate work. RCS managed revisions of individual files; CVS and Subversion organized work around a central repository; distributed systems let developers maintain repositories and exchange history. Centralized systems still allow local editing while disconnected. Git was part of the development of distributed version control, not its beginning.

These choices affect where history and coordination live. A normal full Git clone has local history that can be inspected and extended without contacting a server, while shallow or partial clones deliberately limit what is available. A hosting service adds review, discussion, and automation around repositories; these are distinct from Git’s object model.

Coordination also depends on agreements outside the tool: who reviews a change, which checks matter, how interface changes reach callers, and when a release is ready. Make those agreements explicit enough that a contributor can prepare a useful change without guessing.

Version Control, Code Review, and Collaborative Judgment

The Mental Model of Version Control

Git’s working tree, index, and current commit describe different states. The working tree contains the files you edit. The index, often called the staging area, describes the next snapshot to commit. HEAD identifies the current commit, usually through the current branch. If you stage a file and then edit it again, the later edit is not automatically staged. git diff normally compares the working tree with the index; git diff --cached compares the index with the current commit.

A commit records a tree snapshot, parent references, and metadata such as its message. The tree organizes names and file contents. A root commit has no parent; an ordinary commit usually has one; a merge commit has more than one. The identifier depends on the commit object, including its parents and metadata, not just the visible source files. It identifies content and history, but does not establish that a change is correct or its stated author trustworthy.

A branch is a movable reference to a commit. When one branch tip is an ancestor of another, a fast-forward merge can simply advance the reference without making a new commit. When histories diverge, an ordinary two-branch merge creates a commit with two parents after combining their changes. A squash workflow records the combined changes without preserving that second-parent relationship. Inspect the graph to understand which operation occurred.

Textual compatibility is weaker than behavioral compatibility. One branch may change a configuration value from milliseconds to seconds while another changes a caller in a different file. Git can combine both edits without a conflict marker and still produce the wrong timeout. After resolving a conflict or integrating related changes, check the resulting behavior and interface assumptions.

Rebase reapplies commits onto another base and generally creates new commit identities. Coordinate before rewriting history others use. Revert records a new change intended to undo an earlier change; it can conflict with later work and cannot undo an email already sent or a database operation already performed. The local reflog can help recover recently moved references, but its entries expire and are not a durable backup.

A remote is another repository, not a continuously synchronized folder. git fetch downloads objects and updates configured remote-tracking references; it does not merge them into your current branch. A name such as origin/main represents locally recorded information about the remote, which may be older than the remote’s current state.

What Makes a Good Change

A coherent change answers one reviewable question. Fixing timeout units and reformatting the entire repository in the same diff makes it harder to locate the behavioral change. Separate unrelated work; keep tightly coupled interface and caller changes together when splitting them would leave an unusable intermediate state.

Describe the trigger and resulting behavior, then the reason for the implementation and relevant checks. For a defect, show a case that failed before and succeeds after. Mention an untested assumption when it matters to the decision. Line count is only a rough guide: a one-line permission change can need more scrutiny than a large mechanical rename.

Inspect the staged diff before committing. The file displayed in your editor may contain additional unstaged edits, so testing the working tree does not necessarily test exactly what you are about to commit. A fresh checkout or continuous-integration run can expose that difference.

Code Review as Social-Technical Practice

Read the change description, identify the intended contract, and then inspect the implementation in context. Ask about failure paths, callers, data changes, and the tests that distinguish the intended behavior from a plausible mistake. Use automated formatting and routine checks to leave more attention for these questions.

Make feedback specific: identify a condition, explain its consequence, and suggest a way to check or resolve it. “What happens if this value is zero?” is more actionable than “This looks wrong.” Distinguish a required correction from a question or stylistic preference. The author should answer the reasoning, not merely accumulate approvals.

Review distributes understanding as well as detecting defects. Explain unfamiliar constraints and record decisions that future maintainers will need. Reviewers also have limited context and can miss problems; approval supplements tests and design reasoning rather than replacing them.

AI in Code Review

An AI reviewer can suggest overlooked cases or summarize a large diff. Check whether its comment points to a real path in the changed version. Dismiss or correct a claim when the referenced API, caller, or condition does not exist; repeated speculative comments create review work without evidence.

Use generated feedback as candidate questions. For a consequential change, provide the surrounding contract and verify the claimed failure with an example when possible. More comments do not necessarily mean more defects found, and an empty AI review does not establish that the change is sound.

What Changes With Mastery

You can predict how an operation changes the snapshot, index, references, and commit graph before performing it. You can also prepare a change whose purpose and evidence another person can assess.

Practice in a disposable repository: stage a file, edit it again, and compare both diffs; create a fast-forward and a divergent merge; inspect each graph. Then exchange a small change with another learner and revise its description based on what they could not determine. This combines the technical model with the communication it is meant to support.

Resources

Books and Texts

Pro Git connects the staging workflow, object model, and branching and merging. Wiegley’s guide and Think Like (a) Git provide alternative explanations. Google’s review guidance discusses what to inspect in a change; adapt the process to the task and team rather than copying every organizational convention.

Book Role Type
Chacon & Straub, Pro Git (2nd ed., free) Git workflow and object model Reference
Wiegley, “Git from the Bottom Up” (free) Graph model from the ground up Depth
“Think Like (a) Git” (free) The mental model for Git fluency Entry
Google “How to do a code review” (free) Code review practice, concise and applicable Practice

Courses and Interactive Tools

Learn Git Branching makes changes to the commit graph visible. Pair it with a small local repository so that you also observe the working tree and index. Missing Semester explains the data model; GitHub Skills and the Atlassian tutorials supply workflow exercises. Distinguish a hosting platform’s interface from the underlying Git operation.

Course Platform Type
Learn Git Branching (free) learngitbranching.js.org Practice
MIT Missing Semester: Version Control (free) missing.csail.mit.edu Entry
GitHub Skills (free) github.com/skills Practice
Atlassian Git Tutorials (free) atlassian.com/git/tutorials Entry

Practice, Tools, and Projects

Inspect the graph while practicing commits and merges, then exchange a small reviewable change. For operations involving remote or rewritten history, consult the references for fetch, rebase, revert, and reflog. Commit-message conventions can aid tooling, but a conventional prefix does not supply the reason or evidence for a change.

Resource Platform Type
Visualizing the commit graph (git log –graph) Git Practice
Pull request preparation and review workflow GitHub / GitLab Practice
Regular code review practice Team / open source Practice
Conventional Commits specification (free) conventionalcommits.org Reference

Traps

Trap Why it misleads Better response
Memorizing commands without states The working tree, index, and commit can differ. Predict which state a command reads and changes.
Assuming every merge adds two parents Fast-forward and squash workflows have different histories. Inspect the graph and understand the chosen operation.
Equating a clean merge with compatibility Changes in different files can disagree about a contract. Test the combined behavior and interface assumptions.
Rewriting shared history without coordination Others may depend on the old commit identities. Agree on the workflow and recovery before rewriting.
Reviewing only style or line count Small changes can have large behavioral effects. Focus on requirements, failures, and callers.
Treating review approval as proof Human and automated reviewers have incomplete information. Combine review with independent checks and explicit assumptions.

中文

协作既需要记录修改,也需要判断修改合在一起后的影响。版本控制记录版本及其关系;代码审查检查建议修改是否解决了目标问题,是否适合周围系统。两者都不能单独证明正确性。

协作的基本单位,是别人能够理解的一次修改:行为如何改变、为何改变、依据是什么。清楚的说明与范围集中的差异能帮助判断;合并成功只说明版本控制操作完成了。

前置知识与联系:编程(§2.1)、代码阅读(§8.3)与代码编写(§8.4)。软件过程(§7.3)说明审查和集成在交付流程中的位置。

这项能力的形状:协调并行工作与共享判断

版本控制系统发展出了不同的协作方式。RCS 管理单个文件的修订;CVS 与 Subversion 围绕中央仓库组织工作;分布式系统允许开发者各自维护仓库并交换历史。集中式系统也允许断网时编辑本地文件。Git 是分布式版本控制发展的一部分,并不是它的起点。

这些选择影响历史记录与协作集中在哪里。通常,完整的 Git 克隆拥有本地历史,可以不连接服务器就查看和增加提交;浅克隆或部分克隆则有意限制本地保存的内容。托管服务围绕仓库增加审查、讨论和自动化,它们与 Git 的对象模型是不同的层次。

协作还依赖工具之外的约定:由谁审查、哪些检查重要、接口变化怎样通知调用者,以及何时可以发布。把这些约定写清楚,贡献者才能准备有用的修改,而不必猜测。

版本控制、代码审查与协作判断

版本控制的心智模型

Git 的工作区、索引和当前提交描述不同状态。工作区包含你正在编辑的文件;索引通常称为暂存区,描述下一次准备提交的快照;HEAD 标识当前提交,通常通过当前分支间接指向它。暂存文件后再次编辑,后来的修改不会自动进入暂存区。git diff 通常比较工作区与索引;git diff --cached 比较索引与当前提交。

一个提交记录树快照、父提交引用,以及提交说明等元数据。树组织文件名称和内容。根提交没有父提交;普通提交通常有一个;合并提交有多个。提交标识取决于整个提交对象,包括父提交和元数据,而不只是可见的源文件。它标识内容与历史,却不能证明修改正确,也不能证明所写的作者身份可信。

分支是指向提交的可移动引用。如果一个分支顶端是另一个的祖先,快进合并可以只向前移动引用,不创建新提交。当历史分叉时,普通的双分支合并会在整合修改后创建有两个父提交的提交。压缩合并流程记录合并后的修改,但不保留第二个父提交关系。查看提交图,才能知道实际发生了哪种操作。

文本兼容弱于行为兼容。一个分支可能把配置值从毫秒改成秒,另一个分支则修改不同文件中的调用者。Git 可以不产生冲突标记就合并两者,结果却使用错误的超时时间。解决冲突或整合相关修改后,还应检查最终行为与接口假设。

变基把提交重新应用到另一个基础上,通常会产生新的提交标识。重写别人正在使用的历史前,应先协调。还原操作记录一次新修改,试图撤销先前修改;它可能与后续工作冲突,也不能撤回已经发送的邮件或已经执行的数据库操作。本地 reflog 有助于恢复近期移动的引用,但记录会过期,不能充当长期备份。

远程仓库是另一个仓库,不是持续同步的文件夹。git fetch 下载对象并更新配置指定的远程跟踪引用,不会把它们合并到当前分支。origin/main 这样的名称,表示本地记录的远程信息,可能落后于远程仓库的当前状态。

什么构成一个好的改动

一次连贯的修改回答一个能够审查的问题。修复超时单位时顺便格式化整个仓库,会让行为变化更难找到。应拆开无关工作;但如果拆分会使中间版本无法使用,就应把紧密关联的接口与调用者修改放在一起。

先说明触发条件和修改后的行为,再解释实现理由及相关检查。修复缺陷时,给出修改前失败、修改后成功的案例。如果某个未经测试的假设影响决定,就说明它。行数只是粗略参考:一行权限修改,可能比大批机械重命名更需要仔细审查。

提交前检查暂存差异。编辑器里显示的文件可能还有未暂存修改,因此测试工作区,不一定是在测试即将提交的确切内容。新检出的版本或持续集成运行,可以暴露这种差异。

代码审查作为社会—技术实践

先读修改说明,明确预期约定,再结合上下文检查实现。关注失败路径、调用者、数据变化,以及哪些测试能区分目标行为和一个看似合理的错误。用自动格式化和常规检查处理重复工作,把注意力留给这些问题。

反馈应具体:指出条件,解释后果,再建议检查或解决方法。“这个值为零时会怎样?”比“这里看起来不对”更容易采取行动。区分必须修正的问题、待讨论的疑问和风格偏好。作者需要回应理由,而不只是收集批准。

审查还会传播理解。解释不熟悉的约束,记录未来维护者需要的决定。审查者的上下文也有限,也会漏掉问题;批准补充测试与设计推理,不能代替它们。

AI 在代码审查中的作用

AI 审查可以提出可能遗漏的案例,或概括较大的差异。检查评论是否指向修改后版本中的真实路径。如果引用的 API、调用者或条件不存在,就应排除或纠正这个判断;反复出现的猜测性评论,只会增加缺少证据的审查工作。

把生成反馈当作候选问题。对于影响较大的修改,应提供周围的接口约定,并尽可能用例子验证声称的失败。评论更多不一定代表发现了更多缺陷;AI 没有提出问题,也不能证明修改可靠。

熟练之后会发生什么变化

执行操作之前,你能预测它怎样改变快照、索引、引用和提交图;也能准备一次让别人判断目的与证据的修改。

在练习仓库中,暂存一个文件,再次编辑,并比较两种差异;分别创建快进合并与分叉历史的合并,查看对应提交图。然后与另一位学习者交换一次小修改,根据对方无法判断的地方修订说明。这样可以把技术模型与它要支持的沟通结合起来。

资源

书籍与文本

《Pro Git》联系了暂存流程、对象模型与分支合并。Wiegley 的指南与 Think Like (a) Git 提供其他解释方式。Google 的审查指南讨论修改中需要检查的内容;应根据任务与团队调整流程,不必照搬全部组织约定。

书籍 作用 类型
Chacon & Straub,Pro Git(第 2 版,免费) Git 流程与对象模型 参考
Wiegley,“Git from the Bottom Up”(免费) 从底层建立图模型 深入
“Think Like (a) Git”(免费) Git 流利度所需的心智模型 入门
Google “How to do a code review”(免费) 简洁且可应用的代码审查实践 实践

课程与交互工具

Learn Git Branching 展示提交图怎样变化。结合小型本地仓库练习,还能观察工作区与索引。Missing Semester 解释数据模型;GitHub Skills 和 Atlassian 教程提供流程练习。应区分托管平台界面与底层 Git 操作。

课程 平台 类型
Learn Git Branching(免费) learngitbranching.js.org 实践
MIT Missing Semester: Version Control(免费) missing.csail.mit.edu 入门
GitHub Skills(免费) github.com/skills 实践
Atlassian Git Tutorials(免费) atlassian.com/git/tutorials 入门

实践、工具与项目

练习提交与合并时查看提交图,再交换一次范围明确的修改进行审查。涉及远程或重写历史时,查阅 fetch、rebase、revert 和 reflog 参考。提交说明约定有助于工具处理,但一个符合约定的前缀,不能补上修改理由与证据。

资源 平台 类型
查看提交图(git log –graph) Git 实践
Pull request 准备与审查工作流 GitHub / GitLab 实践
定期代码审查实践 团队 / 开源 实践
Conventional Commits 规范(免费) conventionalcommits.org 参考

陷阱

误区 为什么会误导 更好的做法
只背命令,不区分状态 工作区、索引和提交可能不同。 预测命令读取和修改哪个状态。
认为每次合并都增加两个父提交 快进与压缩合并产生不同历史。 检查提交图,理解所选操作。
把无冲突合并等同于兼容 不同文件中的修改也可能违背同一约定。 检查组合后的行为与接口假设。
未协调就重写共享历史 别人可能依赖旧提交标识。 重写前商定流程与恢复方法。
只根据风格或行数审查 小修改也可能产生较大行为影响。 关注需求、失败和调用者。
把审查批准当作证明 人工和自动审查掌握的信息都不完整。 结合独立检查,并明确假设。