注解目录
1、关于 Git
1.1Git 今生
(Git 和 Linux 的生父都是 Linus,振南给你讲讲当初关于 Git 的爱恨情愁,其背后其实是开源与闭源两左阵营的明争暗斗。)
1.2Git的爆发
(Git 超越时代的分布式思想。振南再给你讲讲旧金山三个年轻人创办 GitHub,打败Google,逆袭上位的创业故事。据说 GitHub 服务器要放到火星去? )
2、用Git代码
2.1Git本地化化使用
(以实例来讲解代码仓库的创建、提交、分支等基础内容。)
2.2 Git 的远端使用
(以实例来讲解仓库的克隆、推送等基础内容。)
2.3代实(Git 绝不会把代码弄丢。一次有惊无险的代码追回经历,根源是对 Git 机制理解不深。)
3、用Git 管理硬件PCB
(对于硬件资源你是如何管理的? final _final _打死不改_final_1.2.zip? 还是用 Git 吧。)
3.1Git的增量
(Git 具体是如何对资源进行管理的? )
3.2 AD 中的Git
(AD 是原生支持 Git 的,让我们把它利用起来。)
3.3PCB 工程的协作开发
(团队协作中的冲突是如何产生的?如何解决冲突? )
2
用 Git管理软件代码
2.1Git本地化化使用
当你在开发一个完全独立的,不需要公开或多人协作的项目时,就可以使用 Git 的本地化仓库。下面振南举例进行说明。
安装好 Git 之后,在要管理的代码工程目录下单击右键,选择 Git Bash,如图 4.4 所示。
然后 git init,这样就创建了一个本地的仓库。对,就是这么简单。创建成功后,可以看到个名为.git 的目录,如图 4.5 所示。
从图中我们可以看到(master),这是当前仓库所处的分支。分支(Branch)是 Git 的一个重要概念。一个仓库可能会有很多分支,其中有一个分支为默认主分支,一般主分支名称为master 或 main。分支可以被创建、拷贝和删除,而各分支之间可以合并。这些是 Git 最最基本的一些操作,请大家深入去理解。
OK,我们现在创建了一个空仓库,而且它有一个主分支 master,如图 4.6 所示。
对,它就是这么空空如也。接下来我们把要进行版本管理的文件添加到仓库中,使用 gitadd 命令,如图 4.7 所示。
只有被添加到仓库里来的文件,才能进入到 git 的版本管理体系中来。一个项目的文件可能会非常多,难道要一个个去 add 吗?如果真是这样,那 Git 就不会有今天的辉煌了。直接
![](https://file.jishuzhan.net/article/1723262366994403330/d9fbdbd8dc59626107bcca051045db8b.webp)
图4.4 代码工程目录下右键选择 Git Bash
![](https://file.jishuzhan.net/article/1723262366994403330/833b30b9d50909d9ef6b43d307c22963.webp)
图4.5 创建本地的git仓库
![](https://file.jishuzhan.net/article/1723262366994403330/859c4b16bd030330b8e7182b925a79ea.webp)
图4.6 一个只有一个主分支 master的空仓库
![](https://file.jishuzhan.net/article/1723262366994403330/28b11368236d2afb85987af9f8bac55a.webp)
图4.7 向仓库中添加文件以对其进行版本管理
使用 git add.即可。但是这样又出现一个问题,我可能并不想把所有文件都添加到仓库中,比如一些编译的中间文件.obi..o 等,因为对这些文件进行版本管理毫无意义,而且还会使仓库越来越臃肿。为什么会越来越臃肿?往后看。
为了解决这个问题,git 提供了.gitignore 这个文件,我们可以把不想加入到仓库中的文件弓到此文件中,比如 *.obi。这样我们执行 git add.的时候,git 就会自动为我们忽略这些文件。
OK.现在我们将这个目录下的所有文件都加入到仓库中,如图 4.8 所示。
![](https://file.jishuzhan.net/article/1723262366994403330/c7587d328ab685a7a8afa6aeba952971.webp)
图4.8 向仓库中添加所有文件
如果文件比较多,这个操作可能会比较花时间接下来,我们来尝试进行第一次提交 commit,如图 4.9 所示
![](https://file.jishuzhan.net/article/1723262366994403330/442a1ec8cfbe183e4ed7781b49b56106.webp)
图4.9 尝试进行第一次提交
git 提示"Please tell me who you are"好吧,那我们用提示中的 git config 命令来设置账户邮箱和用户名,如图 4.10 所示。
再次尝试进行 commit,如图 4.11 所示。
可以看到 git 罗列出了我们前面 add 的所有文件,这说明这些文件确实已经进入到 git 的管理体系中了。在提交的时候,可以通过-m 来添加一些注释,来对此次提交进行一些必要的描述。
![](https://file.jishuzhan.net/article/1723262366994403330/5202f5fead4de31b8c4e3fcc60e1b36c.webp)
图4.10 设置账户邮箱和用户名
![](https://file.jishuzhan.net/article/1723262366994403330/c45f458ae6df525ec6d31eaacf9e5e5d.webp)
图4.11 对代码进行提交
我们可以使用 git log 来查看当前分支曾经的提交历史,如图 4.12 所示
![](https://file.jishuzhan.net/article/1723262366994403330/612a42647282529d73b0d62e8a43fe35.webp)
图4.12 通过git log查看当前分支的提交历史
好吧,我们只提交过一次
接下来,我们对文件作一些修改(把 arch_flags.c 文件内容清空),如图 4.13 所示。
然后再提交一次,如图 4.14 所示。
此时,如果我们想看一下上一个版本的代码,该如何操作?仔细观察每一次 commit,git都会生产一个 commit-id(40 个字符),通过它我们可以进入任何一次提交,去查看当时的代码,如图 4.15 所示。
此时,我们再去看一下刚才修改的 arch_flags.c 这个文件,如图 4.16 所示。可以看到,arch_flag.c 文件又恢复了原来的内容,是不是很神奇?这就是 Git 为我们带来的版本管理强大功能的冰山一角。
进入某个 commit 后,可以查看代码,但是并不能修改它,因为每一次 commit 都是一个固定的版本。那如何基于某一个中间 commit 进行后续开发呢? 那我先要问问你为什么会有这种自废武功的操作?你理直气壮地说:"因为我后悔了,我对这个 commit 之后的代码开发不满意,我希望回去重新来!"OKGit 给你后悔药。
我们让代码回滚,如图 4.17 所示。
![](https://file.jishuzhan.net/article/1723262366994403330/ffdf942ffed4959f5fbce43648603e63.webp)
图4.13 对文件做一些修改
![](https://file.jishuzhan.net/article/1723262366994403330/099114d381ce8280221dd1369a22f949.webp)
图4.14 对代码再一次提交
![](https://file.jishuzhan.net/article/1723262366994403330/cbcfc0e72a9e1cd423daca8e3e723418.webp)
图4.15 使用git checkout进入到某一次提交
![](https://file.jishuzhan.net/article/1723262366994403330/4925644a357210fe83fd671abc4a9388.webp)
图4.16 切换commit之后arch_flags.c文件恢复了原来的内容
![](https://file.jishuzhan.net/article/1723262366994403330/1514201719001e5ad8d7bb411f7d801b.webp)
图4.17 将代码回滚到某一个commit
上图中,先从 commit 的临时分支切回到 master 分支,然后使用 git reset 命令将版本回滚到某个 commit 上。最后,再次 git log 就会发现,第二次提交已经消失了。我们这个时候就可以开始在这颗"后悔药"上继续开发了。
但是你又怎么保证你不会后悔吃了后悔药? 有点作,no 作 no Die,想好再干。OK,Git 满足你,如图 4.18 和图 4.19 所示。
![](https://file.jishuzhan.net/article/1723262366994403330/a0f77d1a667e7bfbac6dad6f447d8f8f.webp)
图4.18 从 master分支的某个commit开出一个新的分支test
![](https://file.jishuzhan.net/article/1723262366994403330/ed82b3aa79d707bd4dea9ddde45fd6b4.webp)
图4.19 从 master分支的某个commit开出一个新的分支test(示意图)
我们可以从 master 分支的某个 commit 开出一个新的分支,然后在这个新的分支上继续开发。最后再合并到 master 上,如图 4.20~10.22 所示。
![](https://file.jishuzhan.net/article/1723262366994403330/e2414b6a85b846d9700e2253ef0490ba.webp)
图4.20 在test分支上对arch_flags.c文件作一些修改
![](https://file.jishuzhan.net/article/1723262366994403330/10786ca8fe41b49992be3c5506a7ace1.webp)
图4.21 在test分支上对代码进行提交
![](https://file.jishuzhan.net/article/1723262366994403330/34d7abc06de829d433acf8fa7042bfff.webp)
图4.22 将test分支合并到 master分支上
图 4.22因为清屏的问题,没有截到图。过程是先 checkout master,然后 git merge test。这个时候会提示 arch_flags.c 有冲突,并且自动处理冲突失败(需要手动处理),同时标识变成了(masterlMERGING),说明当前分支正在进行合并。
有人会问:"冲突是怎样产生的? 冲突是什么样的?"原则上来说,在两个分支的同一个文件中,同一行的内容不同,那么就会产生冲突,而且 Git 并不能自动处理,因为它根本不知道该舍谁留谁。
冲突的解决通常需要借助于一些工具,比如 kdiff3 等。我一直在使用 VScode,我也建议大家使用它,因为它的功能实在是太强大了,如图 4.23 示。
![](https://file.jishuzhan.net/article/1723262366994403330/37b78e122617f79d59ccea242e87abf7.webp)
图4.23 使用 VScode对冲突进行解决
上面说,冲突的本质是一个去留的问题。仔细观察上图,会发现代码中有一个分割线==-==,它上面是 master 分支当前这一行的内容,下面则是合并的源分支,即 test 分支此行的内容。一个称为 Current Change选择,另一个称为Incoming 你需要在这两者之间做出选择。在冲突的顶端有几个选项Accept Current Change和Accept Incoming Change,我们选择后者。在解决了冲突之后我们对 master分支进行再一次commit,标识中的MERGING就消失了,如图 4.24 所示。
![](https://file.jishuzhan.net/article/1723262366994403330/c7a54ff648e533096e48a68c16a86b34.webp)
图4.24 对完成 merge的 master分支进行commit
此时,似乎 test 分支已经没有存在的必要了,我们可以将它删除,使用命令 git branch-delete test 。
当然,如果我们发现在 test 分支上于不下去了,又想回到 master 分支,那么你可以直接干掉 test 分支,回归 master。
以上一整套的操作其实映射出几个问题:
(1) 不要轻易地删除分支或回滚,以及其他可能造成数据丢失的行为,三思而行(虽然在git 的体系下,并不会真正的造成丢失,后面会有一个数据拯救追回的实例);
(2) 你应该有一个主分支,比如 master 或 man,并目秉持亚肃的态度,不轻易地直接对其进行改动。并保证主分支上的代码是相对成熟的:
(3) 每开一个子分支一定要知道为什么开它,以及它的使命是什么? 原则上来说,一切子分支都应该为主分支服务。
以上振南只是对 Git 的本地化操作的一些皮毛进行了介绍,我想已经足够大家应付一般的情况了。