Git
我们可以把 Git 仓库日常的操作比作一座 图书馆,图书馆中每个人家里都有自己的工作台、书架和书本,图书馆就是 Git 仓库,而书本就是代码。接下来我们用这个图书馆的比喻来形容一下 Git 的各种操作。
- 克隆(clone):
你从图书馆(远程仓库)借了一整套书到你家里(本地仓库)。这时,你的家里(本地仓库)就有了一模一样的书架和书本。
- 分支(branch):
当你想要写新内容(修改代码)时,你可以从书架上拿下一本书(master 分支),然后复印一份(创建分支)。你把复印的这本书带到自己的工作台上(例如:Xiruihome 分支),开始涂涂改改,但你不会影响原来的书(master 分支上的内容)。
- 提交(commit):
每次你修改了一些内容(写了代码),你都把它记录下来,就像给书本加了一个新的注释页(一次提交)。这些注释页让你随时可以回头看看之前都做了哪些改动。
- 推送(push):
当你在自己的复印本上完成了所有修改,觉得很满意后,你就把它送回图书馆(远程仓库),放到一个新的架子(远程的 Xiruihome 分支)上。现在,所有来图书馆的人都可以看到你的这本复印本了。
- 拉取(pull):
有一天,你听说图书馆(远程仓库)的书架上更新了新书,于是你去借阅这本更新的书,并带回家。这就是拉取操作,把别人做的改动拿回来,更新到你的本地。
- 合并(merge):
你在工作台上(Xiruihome 分支)完成了改动,觉得这些内容应该加到主书本(master 分支)里,于是你把它们合并在一起。现在,主书本上有了你和其他人写的内容。
- 冲突(conflict):
但是,如果有人在你改动的同时,也在主书本上做了类似的修改,当你想把你的内容合并到主书本时,发现两个人的改动有些不一致。这时候,你就得停下来,仔细比较两人的笔记,并选择保留谁的内容。这就是 Git 冲突,合并时需要手动处理。
- 暂存区(staging area):
在你决定要提交之前,你可以先把修改内容放到桌子旁边的一个小篮子里(暂存区)。在篮子里整理好了,确认无误之后再交给图书管理员(commit 提交)。这样避免一次性把所有书页都乱塞进去。
- 回滚(revert/reset):
如果有一天你觉得修改得不好,想回到以前的状态,你可以从图书馆的记录中找回之前的书页,把错误的部分擦掉(回滚或重置),就好像这些错误的改动从未发生过一样。
- 远程仓库(remote):
图书馆是公共的,大家可以借阅书本和贡献修改;而你家里的书架是私人的,你可以自由改动。图书馆和你家的书架之间通过 push
(送书)和 pull
(借书)来保持同步。
小结:
- 克隆:从图书馆借书到家里。
- 分支:创建副本在自己的工作台上修改。
- 提交:每次改动就给书本加注释页。
- 推送:把副本送回图书馆的一个新架子上。
- 拉取:从图书馆借阅更新后的书本。
- 合并:把修改合并回主书本。
- 冲突:当两个人的笔记有冲突时,需要调解。
- 暂存区:修改前先放到篮子里整理。
- 回滚:擦除错误笔记,恢复到之前的版本。
这个比喻是不是让 Git 的日常操作变得更有趣了呢?
关于暂存区的概念
暂存区(staging area)其实在 Git 中是非常重要的一个概念,它的主要作用是给你更灵活的控制,可以分批次地整理和提交你的代码。虽然有时候它看起来像是多了一步操作,但它的作用非常强大,特别是在更复杂的开发流程中。我们来详细看看它的几个关键用途和好处。
- 分阶段提交:
在实际开发中,你可能会同时修改多个文件,涉及不同功能或修复不同问题。如果没有暂存区,你的提交就只能一次性把所有的改动一起提交,而暂存区允许你选择性地把一些改动放进“篮子”(暂存区),而暂时不提交其他改动。这样,你可以做到:
- 按功能提交:你可以先提交一部分和功能 A 相关的改动,再提交另一部分和功能 B 相关的改动,这使得提交记录更干净、条理清晰。
- 避免提交无关内容:如果你正在修复一个 bug,但同时也改了一些格式或注释,暂存区让你可以只提交与 bug 修复相关的改动,避免混入无关的修改。
- 精细控制提交内容:
暂存区允许你对具体的提交内容进行精细控制。Git 提供了 git add -p
(交互式添加)功能,允许你逐个查看每个修改的部分,选择是否将它们加入暂存区。这在处理大文件或者复杂改动时非常有用,你可以手动选择提交哪些部分的改动。
例如,如果你对同一个文件中的多个不同部分进行了修改,你可以只暂存并提交一部分,剩下的部分可以在之后继续修改后再提交。这个特性在分割大提交、保持提交记录清晰时非常有用。
- 检查提交前的内容:
暂存区可以看作是一个“中间区”,你可以在把改动提交之前,将改动暂存起来,然后使用 git diff --staged
来查看已经暂存但还没有提交的内容。这能让你在提交之前仔细检查,确保提交的代码是你想要的内容,避免提交不必要的文件或错误的改动。
- 减少提交错误:
有时你可能会不小心把某些未完成的代码一起提交,如果没有暂存区,你只能一次性提交所有改动,而通过暂存区,你可以挑选那些已经完成的代码提交,而把还没完成的部分留在工作区,继续完善之后再提交。这样可以减少提交错误代码或未完成代码的情况。
- 准备中间状态:
暂存区也可以作为你准备提交的“中间状态”,让你在提交之前有更多的整理和准备空间。例如:
- 你可以把一些改动暂存起来,然后继续进行更多的修改。
- 在你确定所有改动完成且准备好提交时,再从暂存区提交出去。
- 管理冲突:
当你在处理合并时,暂存区也是非常有用的。如果发生冲突,Git 会把冲突文件放在工作区中,你需要手动解决冲突。解决冲突后,你可以将每个解决好的文件逐个放入暂存区,直到所有冲突都解决,再一次性提交。
举例说明:
假设你在项目中做了以下三项工作:
- 修复了一个 bug。
- 添加了一个新功能。
- 格式化了一些代码。
没有暂存区的情况下,这些改动只能一次性提交到 Git 仓库里。可是如果你希望分别提交 bug 修复和新功能,暂存区就很有帮助。你可以先把与 bug 修复相关的文件放入暂存区,提交之后再将新功能的修改放入暂存区,分别提交不同的内容,这样日志就非常清晰,未来回溯代码时也更容易理解。
小结:
- 暂存区帮助你分批提交不同改动,保持提交记录清晰。
- 它允许你选择性暂存部分改动,进行更细粒度的提交。
- 你可以在提交前检查暂存的内容,确保提交正确。
- 在处理复杂的项目时,暂存区有助于减少错误提交和提高工作效率。
因此,虽然暂存区看似多了一步操作,但它提供了更多的灵活性和控制力,尤其在大型项目或需要精确提交的场景下,能大大提升代码管理的质量。
理解暂存区
就好比我在写一堆文件,我把已经写好的文件放在一个小文件夹内,这个小文件夹就相当于暂存区,但我手里的工作并没有停下来,我仍然在写文件,如果老板需要用到文件了,直接拿走小文件夹就可以,并不影响我手中的工作,但是如果没有这个小文件夹,当老板需要文件的时候,我就得停下手中的工作,不管完没完成,一下子全部交给老板。
我们可以用这个“文件夹”和“写文件”的比喻来形象地理解暂存区的作用。
-
小文件夹 = 暂存区:这个小文件夹就是暂存区,你把已经完成的、可以交付的文件放进去,但你手头上还有其他文件正在写,并不受影响。这就像你可以选择性地把部分已经完成的代码放到暂存区,而继续编写或修改其他部分。
-
正在写的文件 = 工作区:你手里正在写的文件相当于 Git 的工作区(工作目录),它代表你正在进行的修改,还没有完成或还不想交付。
-
老板 = 提交操作:当老板来要文件时(需要提交代码),你只把小文件夹里的文件交给他。这相当于你提交到 Git 仓库的代码只是暂存区里的内容,工作区中你还没完成的工作不会被提交。
-
没有小文件夹的情况:如果没有这个小文件夹(暂存区),那老板来要文件时,你只能把手头的所有文件都交出去,不论这些文件是写好了还是没有写完。这种情况下,所有的修改都会一次性提交到 Git 仓库里,可能会导致不必要的内容一起被提交,影响代码质量和后续维护。
这个比喻清晰地表达了暂存区的重要性,它提供了灵活的“中间存储”功能,让你在不打断工作的情况下,有条理地提交已经完成的部分工作。你可以继续手头的修改,同时安全地提交已经完成并经过检验的代码,这样既不会中断当前的工作流程,也可以确保每次提交都是高质量且明确的。