人人都能学编程
English 开始学习
核心 · Git第 3 课 / 共 6 课免费阅读

分支与合并 · Git 与 GitHub

怎么在不弄坏主版本的情况下尝试新东西?

课程目录

为什么需要它

团队里,main 必须永远能用。新功能和实验都在分支上做:分支是独立的一条历史线,做好了可以合并回去,想法不行就直接删掉。GitHub 上的每个 pull request 都是一个分支。

直觉理解

分支只是一个指向某个提交的标签。你提交时,当前所在的那个标签会往前移。

  • git switch -c login:建一个叫 login 的分支并切过去
  • git switch main:切回来;你的文件会变成 main 上的版本
  • git merge login:把 login 的提交合并进你当前所在的分支

如果你工作期间 main 没动,合并就是快进:main 标签直接往前滑。如果两边都有新提交,Git 会创建一个有两个父提交的合并提交。

定义

分支 Branch

A movable name for a line of commits. `main` is just the branch most teams treat as the official one.
一条提交线上可移动的名字。`main` 只是大多数团队当作正式版本的那个分支。

合并 Merge

Combining the work of another branch into the current one, by fast-forward or with a merge commit.
把另一个分支的工作合进当前分支,方式是快进或者生成一个合并提交。

示例

功能分支,快进合并

在互动课里运行

在分支上工作,然后合并进没变过的 main。

git switch -c login
echo "def login(): pass" > login.py
git add login.py
git commit -m "add login"
git switch main
ls
git merge login
ls
逐步执行
  1. L1新分支,而且你已经在上面了。
  2. L4这次提交只在 login 上。
  3. L6回到 main,这里没有 login.py。README.md app.py
  4. L7main 没动过,所以直接往前滑。
  5. L8现在 main 上也有了。README.md app.py login.py

两边都动了:合并提交

在互动课里运行

队友在 main 上的修改和你在分支上的修改动的是不同文件,所以 Git 自动把它们合到一起。

git switch -c search
echo "def search(): pass" > search.py
git add search.py
git commit -m "add search"
git switch main
echo "Now with search" >> README.md
git commit -am "update readme"
git merge search
git log --oneline
逐步执行
  1. L7main 也往前走了。
  2. L8两边都有新提交,所以 Git 生成一个合并提交。
  3. L9合并提交在最上面,它有两个父提交。

常见错误

直接在 main 上干活

在 main 上放半成品会挡住所有人。凡是一次提交做不完的事,都开一个分支。

合并方向弄反

git merge X 是把 X 合进你当前所在的分支。合并前先看 git branch(* 标出你在哪)。

小测验

1. 最后一条命令打印什么?

git switch -c dark-mode
git switch -c fonts
git branch
  1. A
      dark-mode
    * fonts
      main
  2. B
    * dark-mode
      fonts
      main
  3. C
      dark-mode
      fonts
    * main
查看答案

答案:A

switch -c 每次都把你带到新分支上,所以最后在 fonts。

2. 你在 `main` 上运行 `git merge feature`。feature 开始之后 main 没有新提交。会怎样?

  1. A快进:main 移到 feature 的提交上
  2. B一个有两个父提交的合并提交
  3. C冲突
查看答案

答案:A

main 上没有新东西,就没什么可合的:标签直接移动。

动手练习

3 道练习,分三层:先预测程序的输出,再按新需求改程序,最后从零写一个。代码在浏览器里运行,提交马上判题。

  1. 预测输出文件在哪?

    准确写出最后一条命令打印的内容。

  2. 改需求在正确的分支上提交

    这些命令把新功能直接放到了 main 上。改成:提交放在一个叫 wishlist 的新分支上,main 停在 first version。

  3. 从零写完成一个功能

    分支 reviews 上已经有一个完成的提交。把它合并进 main,然后用 git branch -d reviews 删掉这个分支。

在互动课里练这一课

打开互动课,这些例子都能直接改、直接运行,练习题提交马上判题。免费开始,不用注册。

互动课按顺序解锁:前面的课还没学,会先带你到课程地图。

本课术语

术语中文英文定义
Branch分支A movable name for a line of commits.
Merge合并Bringing another branch's commits into the current one.
Fast-forward快进A merge where the branch label just moves forward.