type
status
date
slug
summary
tags
category
icon
password
🌐
如果你是一枚 Coder,但是你不知道 Git,那么你就不是一个菜鸟级别的 Coder,因为你压根不是真正的 Coder,你只是一个 Code 搬运工。但是你如果已经在读这篇文章了,你就已经知道 Git 了。正是 Git & GitHub,让社会化编程成为现实。

版本控制系统

什么是版本控制系统?我为什么要关心它呢?
“版本控制系统是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。 在本书所展示的例子中,我们对保存着软件源代码的文件作版本控制,但实际上,你可以对任何类型的文件进行版本控制。” ——《Pro Git》

关于版本控制

在现实的开发场合中,我们常常会遇到数据文件的备份,保存,以及同步的问题。你可以想象这样的场合:
你在一个研究小组中,小组里的每个人都需要根据自己的分工完成同一份实验报告。一天前,A 同学给你发了一份他本地修改过的报告,你于是在他的基础上完成你的部分。第二天,C 同学把他的报告和 D 同学的报告合并之后又发给了 A 同学,A 同学修改完之后又发给了你,一来一回,你发现你又要重写你负责的部分……
或者,你正在参加一个比赛,时间还很多,你准备优化一部分代码,然后添加一些新功能。调着调着,比赛还剩下半小时,可是新的部分却依然没有调好……无奈之下,你依稀记得你给之前的代码做了备份,可是看着电脑里 新建文件夹 (1) 新建文件夹 (2) 新建文件夹 (3) 新建文件夹 (4) 新建文件夹 (5),你陷入了沉思……
其实,在上面的例子中,我们就已经涉及到了最简单的本地版本控制系统,也就是手动复制文件夹备份的方法。
但是,这种方法往往显得不那么智能,虽然你可以为文件夹打上备注,但也特别容易犯错。比如一不小心删除了重要文件,混淆了当前的工作目录等。
但更大的问题是,当你和不同人共同完成一个项目时,项目的文件该如何以一种合理的方式保持同步?(显然 QQ 群传文件并不是一个好方法)
现代的版本控制系统可以帮助您轻松地(甚至自动地)回答以下问题:
  • 当前模块是谁编写的?
  • 这个文件的这一行是什么时候被编辑的?是谁作出的修改?修改原因是什么呢?
  • 最近的 1000 个版本中,何时/为什么导致了单元测试失败?
notion image

基于快照的版本控制系统

我们首先来看看基于差异的版本控制系统。
  • 相比于复制备份,基于差异的版本控制系统大大缩小了需要的储存空间。
  • 回退版本时需要从头开始一步步回溯,如果文件在版本系统不知晓的情况下修改,所有备份将会损坏丢失。
而在 Git 所管理的项目中,Git 会保存每一个文件的镜像,同时管理一份指向修改前的文件和修改后的文件的索引(类似于指针)。我们在每次向 Git 提交文件时,Git 就会帮我们保存一份文件的镜像(压缩后)和指向它的索引,所以我们称 Git 是基于快照的版本控制系统(甚至可以说 Git 帮我们维护了一个小型的文件系统)。
这样做有很多好处,比如:
  • 保留了差异式系统所需储存空间小的优点。
  • 用户提交新快照时,若文件没有更改,Git 可以直接添加旧的镜像索引到新的提交中。
  • 所有提交都可以在极短时间内完成回溯。
  • 由于 Git 会给所有管理的对象计算 SHA1 校验和(SHA-1 算法特性),以保证文件的完整性。
  • 在用户的所有操作中,几乎都只是向 Git 中添加数据,很少有可能造成数据丢失(所以建议在 Git 储存库中不要存入敏感信息)。
哈希算法示例:
notion image

一些 Git 概念

notion image
  1. blob:Git 的基本储存单元之一,是最简单的对象,一般是文本文件,但也可以是其他内容。
  1. tree:其引用 blob 形成目录,同时也可以引用其他 tree 作为子目录。
  1. commit:向 DAG 图中添加一个节点(快照),这个节点指向表示提交时文件状态的 tree。
  1. ref:类似于指针(便利贴)的作用(给节点的哈希值一个名字),指向当前 DAG 图的状态或者你处于的位置。
      • HEAD:特殊的一个标签,用于指代你的当前储存库在 DAG 图中所处于的位置。
      • master:Git 默认创建的分支名称。
      • <remote>:用于指代远程 Git 服务器所处于的位置。
      • <branch>:用于指代 DAG 图中分支的标签。
Git 实质上是一个含有所有历史快照的 DAG 图(有向无环图)。
notion image
一个常见的 Git 分支图,每个点代表了一个 commit,不同行代表所处的不同分支。
不难看出,Git 只是帮我们保存并维护了两样东西:对象和引用。

Git 的安装与配置

OR:
自带 Git 和一个非常美观的 GUI 😳

命令行操作与技巧

Git 流程

notion image

Add / Commit

Example:

Branch / Checkout / Switch

Example:

Merge / Rebase

Example:
Fast-forward:
当两个分支在同一条未分支的路径上时,Git 会尝试直接移动分支标签进行合并,而不是创建一个新的 commit。
Merge 和 Rebase
两种不同的合并方法,相比于 merge,rebase 在合并时相当于直接把待合并的分支嫁接在了主分支的顶部。
Oh my god it's a conflict!
有时候合并的两个分支含有冲突的内容,Git 会尝试帮我们自动合并,但在无法自动合并时,Git 就会提示我们手动解决冲突。
这是文件合并时遇到冲突时的样子,请不要害怕,这并不意味着我们的文件损坏了,他只是标记了我们需要手动解决冲突的位置。
这是一种标注文件内容差异的格式:GNU-diff。
有些比较智能的 IDE 或者编辑器会将它们标记出来,如 VSCode 会将其显示成这样子:
notion image
我们既可以手动删除不需要的部分,也可以通过 IDE 或者其他图形化的合并工具帮助我们解决冲突,再重新 merge。

Clone / Pull / Push

有时候我们需要和他人进行协作,我们就需要从远端获取我们的代码仓库,这时就需要使用 pull 和 push 了。
Example:
注意:如果你的仓库是由 git init 初始化的,则需要手动添加一下远程 Git 服务器的地址;如果是 git clone 下来的,则远程服务器名称默认为 origin,地址默认为你 clone 时的地址。

Log

有时候你忘记了之前的操作,或者想要查看一下当前仓库的历史状态,则可以使用 Git 的 log 功能。
Example:
输出示例

其它

一些很有意思的命令:git blame git cherrypick ...
进一步了解 Git:

Submodules

Git 的 submodule 功能允许你将一个 Git 仓库作为另一个 Git 仓库的子模块(submodule)包含进来。这在管理大型项目时非常有用,特别是当你需要将多个项目组合在一起时。

Git & GitHub 历史

Git 的历史始于 Linux 内核开源项目的发展需求。在 1991 年至 2002 年间,Linux 内核的维护工作非常繁琐,主要依赖于提交补丁和保存归档。到了 2002 年,Linux 内核项目开始使用一个名为 BitKeeper 的专有分布式版本控制系统来管理代码。然而,到了 2005 年,由于 Linux 内核社区与 BitKeeper 的开发公司 BitMover 的合作关系结束,BitMover 收回了对 Linux 社区的免费授权,这迫使 Linux 社区必须寻找新的版本控制系统。
Linux 的缔造者 Linus Torvalds 决定开发自己的版本控制系统,这就是 Git。Git 的开发目标包括速度、简单的设计、对非线性开发模式的支持、完全分布式,以及能够高效管理大规模项目的能力。Git 在 2005 年诞生,它的发展非常迅速,很快就成为了 Linux 内核的版本控制系统,并逐渐被广泛接受和使用。
Git 的核心理念是分布式版本控制,与传统的集中式版本控制系统不同,Git 允许开发者在本地工作,并且可以在不同的设备之间同步代码,而不需要依赖中央服务器。这种设计使得 Git 在处理大规模项目时更为高效,并且具有更好的网络连接稳定性。
Git 的成功部分归功于它解决了开发者在版本控制中遇到的问题,提供了简单可靠的备份,并允许生成私有的仓库,而不用担心中央仓库的权限问题。此外,Git 的分布式特性和高效的分支管理使得它非常适合大型项目和快速迭代的开发流程。
随着时间的推移,Git 不断成熟和完善,它的易用性不断提高,功能也不断增强。2008 年,GitHub 的上线进一步推动了 Git 的普及,GitHub 为开源项目提供了免费的 Git 存储服务,吸引了大量的开发者和项目迁移到 Git 平台。
GitHub 是一个基于 Git 的版本控制和协作平台,它允许用户托管和管理代码,以及跟踪任务和增强团队合作。GitHub 由 Chris Wanstrath、PJ Hyett 和 Tom Preston-Werner 在 2008 年创立,现在是微软的一部分。

参与开源项目

如何参与 GitHub 上的开源项目?
  • Step 1. 把仓库 fork 到自己的账户下(获得对代码的修改权)。
  • Step 2. 把自己 fork 的 repo 克隆到本地并进行修改(建议新建一个自己的分支)。
  • Step 3. 推送自己的修改,并在原项目页面上提交一个 Pull Request,附上自己修改的简要介绍,等待原作者合并你的修改。
  • Step 4. 作者可能会提出一些问题或者修改建议,此时注意网上交流礼仪。
  • Step 5. 等到作者认为合适之后,会将你的修改合并到主分支中,于是你就成功参与了一个开源项目啦!

通俗易懂的动画教程

一次听明白Github是什么 | git如何与github协作 | github上如何参与开源项目 | github入门教程 【设计师的100个前端问题-06】_哔哩哔哩_bilibili
我的JavaScript + Nodejs高手之路全栈课,就在B站课堂!课程地址 → https://www.bilibili.com/cheese/play/ss1226这一期视频来和大家仔细地介绍下github内容主要分为三个部分:0’30 github简介和基本使用7‘24 git和github的结合使用9’44 github上如何参与开源项目如果没看过上一期 于git的内容 建议先看, 视频播放量 6750、弹幕量 41、点赞数 447、投硬币枚数 336、收藏人数 366、转发人数 35, 视频作者 好奇代码的三木, 作者简介 项目开发与合作,网站开发技术学习,请私信,相关视频:第一个发现用github学大模型的人真的是天才!,C++新GUI框架SIMPLE-UI简介/推广视频(基于OpenGL),要是计算机起源于我国...,【科普】用代码写成的程序是如何工作的,大龄程序员的那场聚会,改变了我的一生,真的笑不活了,区区二本也敢来面试腾讯、阿里这些大厂,校招做不到这些,洗洗睡吧!,高中生秀黑客技术,惊呆班上同学??【网络安全/黑客技术】,【科普】代码是什么 (下) | 计算机语言 编程语言原来还有这一手,「Github一周热点46期」大模型OCR、IPTV直播源、工作流程自动化、下一代信息浏览器和下载金融数据工具,央视:网安领域人员缺口300万,现实:很多人连工作都找不到!
一次听明白Github是什么 | git如何与github协作 | github上如何参与开源项目 | github入门教程 【设计师的100个前端问题-06】_哔哩哔哩_bilibili
相关文章
线上课 #18:研究性学习开题仪式 & 如何科学地提问
Lazy loaded image
邮箱添加别名教程
Lazy loaded image
线上课 #16:Git & GitHub 教程
Lazy loaded image
『社团英雄纪念碑』上线
Lazy loaded image
『林桛杨高』Demo 带你漫游杨高
Lazy loaded image
算法竞赛入门教程
Lazy loaded image
『林桛杨高』Demo 带你漫游杨高线上课 #11:算法复杂度与排序算法入门
Loading...
DrimTech
DrimTech
一群热爱信息技术,善于创造的羊羔
最新发布
线上课 #18:研究性学习开题仪式 & 如何科学地提问
2025-1-13
线上课 #17:栈与队列
2025-1-13
『林桛杨高』Demo 带你漫游杨高
2025-1-9
直面挑战,追求卓越——DrimTech 2024
2024-12-31
DrimTech 祝大家 1024 程序员节快乐
2024-12-31
邮箱添加别名教程
2024-12-29
公告
🎉 drim.cc 🎉
DrimTech 官方域名,它来了!