
我们假设你正在开发一个项目里面有三个文件index.html主页、style.css样式和app.js逻辑。 初始状态 (Commit A)你刚建好项目提交了初始版本。文件状态index.html空文件style.css空文件app.js空文件 第一次提交 (Commit B)提交信息“添加网页标题”你做了什么你在index.html里写了一行代码。Commit B 的改动补丁index.html1行h1欢迎来到我的网站/h1当前文件状态index.html包含h1欢迎来到我的网站/h1style.css空app.js空 第二次提交 (Commit C)提交信息“添加红色样式”你做了什么你在style.css里写了样式并且修改了index.html引入了这个样式。Commit C 的改动补丁style.css1行body { color: red; }index.html1行link relstylesheet hrefstyle.css当前文件状态HEADindex.html包含h1...和link...style.css包含body { color: red; }app.js空 第三次提交 (Commit D)提交信息“添加点击弹窗”你做了什么你在app.js里写了逻辑并且再次修改了index.html引入脚本。Commit D 的改动补丁app.js1行alert(Hello!);index.html1行script srcapp.js/script当前文件状态HEADindex.html包含h1...、link...和script...style.css包含body { color: red; }app.js包含alert(Hello!); 现在执行git revert C你的意图你不想要“红色样式”了想撤销 Commit C。Git 的内心独白“Commit C 做了两件事1. 在style.css加了红色代码2. 在index.html加了 link 标签。我要反向操作1. 删掉style.css里的红色代码2. 删掉index.html里的 link 标签。”生成的新提交 (Commit E - Revert C)style.css-1行body { color: red; }index.html-1行link relstylesheet hrefstyle.css执行后的文件状态index.html包含h1...和script...(注意link标签消失了但script还在)style.css空文件 (红色代码消失了)app.js包含alert(Hello!);(弹窗逻辑还在) 紧接着执行git revert D你的意图你连弹窗也不想要了想撤销 Commit D。Git 的内心独白“Commit D 做了两件事1. 在app.js加了 alert2. 在index.html加了 script 标签。我要反向操作1. 删掉app.js里的 alert2. 删掉index.html里的 script 标签。”生成的新提交 (Commit F - Revert D)app.js-1行alert(Hello!);index.html-1行script srcapp.js/script最终文件状态index.html只包含h1欢迎来到我的网站/h1style.css空文件app.js空文件 总结文件是怎么变回去的表格文件初始 (A)提交B后提交C后提交D后Revert C 后Revert D 后index.html空有标题有标题样式链接有标题样式脚本有标题脚本(样式链接被删)有标题(脚本也被删)style.css空空有红色代码有红色代码空(红色代码被删)空app.js空空空有弹窗代码有弹窗代码空(弹窗代码被删)核心逻辑Revert 就像“橡皮擦”它只擦除特定那一次提交留下的痕迹完全不管其他提交做了什么。即使你撤销了中间的 C后面的 D 依然稳如泰山直到你专门去撤销 D。就是说revert是反向操作具体选择的那一次的内容