分支与合并 · 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逐步执行
- L1新分支,而且你已经在上面了。
- L4这次提交只在 login 上。
- L6回到 main,这里没有 login.py。
README.md app.py - L7main 没动过,所以直接往前滑。
- 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逐步执行
- L7main 也往前走了。
- L8两边都有新提交,所以 Git 生成一个合并提交。
- L9合并提交在最上面,它有两个父提交。
常见错误
直接在 main 上干活
在 main 上放半成品会挡住所有人。凡是一次提交做不完的事,都开一个分支。
合并方向弄反
git merge X 是把 X 合进你当前所在的分支。合并前先看 git branch(* 标出你在哪)。
小测验
1. 最后一条命令打印什么?
git switch -c dark-mode
git switch -c fonts
git branch查看答案
答案:A
switch -c 每次都把你带到新分支上,所以最后在 fonts。
2. 你在 `main` 上运行 `git merge feature`。feature 开始之后 main 没有新提交。会怎样?
查看答案
答案:A
main 上没有新东西,就没什么可合的:标签直接移动。
动手练习
3 道练习,分三层:先预测程序的输出,再按新需求改程序,最后从零写一个。代码在浏览器里运行,提交马上判题。
- 预测输出文件在哪?
准确写出最后一条命令打印的内容。
- 改需求在正确的分支上提交
这些命令把新功能直接放到了 main 上。改成:提交放在一个叫
wishlist的新分支上,main 停在first version。 - 从零写完成一个功能
分支
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. |