注解目录
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 就不会有今天的辉煌了。直接
图4.4 代码工程目录下右键选择 Git Bash
图4.5 创建本地的git仓库
图4.6 一个只有一个主分支 master的空仓库
图4.7 向仓库中添加文件以对其进行版本管理
使用 git add.即可。但是这样又出现一个问题,我可能并不想把所有文件都添加到仓库中,比如一些编译的中间文件.obi..o 等,因为对这些文件进行版本管理毫无意义,而且还会使仓库越来越臃肿。为什么会越来越臃肿?往后看。
为了解决这个问题,git 提供了.gitignore 这个文件,我们可以把不想加入到仓库中的文件弓到此文件中,比如 *.obi。这样我们执行 git add.的时候,git 就会自动为我们忽略这些文件。
OK.现在我们将这个目录下的所有文件都加入到仓库中,如图 4.8 所示。
图4.8 向仓库中添加所有文件
如果文件比较多,这个操作可能会比较花时间接下来,我们来尝试进行第一次提交 commit,如图 4.9 所示
图4.9 尝试进行第一次提交
git 提示"Please tell me who you are"好吧,那我们用提示中的 git config 命令来设置账户邮箱和用户名,如图 4.10 所示。
再次尝试进行 commit,如图 4.11 所示。
可以看到 git 罗列出了我们前面 add 的所有文件,这说明这些文件确实已经进入到 git 的管理体系中了。在提交的时候,可以通过-m 来添加一些注释,来对此次提交进行一些必要的描述。
图4.10 设置账户邮箱和用户名
图4.11 对代码进行提交
我们可以使用 git log 来查看当前分支曾经的提交历史,如图 4.12 所示
图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 所示。
图4.13 对文件做一些修改
图4.14 对代码再一次提交
图4.15 使用git checkout进入到某一次提交
图4.16 切换commit之后arch_flags.c文件恢复了原来的内容
图4.17 将代码回滚到某一个commit
上图中,先从 commit 的临时分支切回到 master 分支,然后使用 git reset 命令将版本回滚到某个 commit 上。最后,再次 git log 就会发现,第二次提交已经消失了。我们这个时候就可以开始在这颗"后悔药"上继续开发了。
但是你又怎么保证你不会后悔吃了后悔药? 有点作,no 作 no Die,想好再干。OK,Git 满足你,如图 4.18 和图 4.19 所示。
图4.18 从 master分支的某个commit开出一个新的分支test
图4.19 从 master分支的某个commit开出一个新的分支test(示意图)
我们可以从 master 分支的某个 commit 开出一个新的分支,然后在这个新的分支上继续开发。最后再合并到 master 上,如图 4.20~10.22 所示。
图4.20 在test分支上对arch_flags.c文件作一些修改
图4.21 在test分支上对代码进行提交
图4.22 将test分支合并到 master分支上
图 4.22因为清屏的问题,没有截到图。过程是先 checkout master,然后 git merge test。这个时候会提示 arch_flags.c 有冲突,并且自动处理冲突失败(需要手动处理),同时标识变成了(masterlMERGING),说明当前分支正在进行合并。
有人会问:"冲突是怎样产生的? 冲突是什么样的?"原则上来说,在两个分支的同一个文件中,同一行的内容不同,那么就会产生冲突,而且 Git 并不能自动处理,因为它根本不知道该舍谁留谁。
冲突的解决通常需要借助于一些工具,比如 kdiff3 等。我一直在使用 VScode,我也建议大家使用它,因为它的功能实在是太强大了,如图 4.23 示。
图4.23 使用 VScode对冲突进行解决
上面说,冲突的本质是一个去留的问题。仔细观察上图,会发现代码中有一个分割线==-==,它上面是 master 分支当前这一行的内容,下面则是合并的源分支,即 test 分支此行的内容。一个称为 Current Change选择,另一个称为Incoming 你需要在这两者之间做出选择。在冲突的顶端有几个选项Accept Current Change和Accept Incoming Change,我们选择后者。在解决了冲突之后我们对 master分支进行再一次commit,标识中的MERGING就消失了,如图 4.24 所示。
图4.24 对完成 merge的 master分支进行commit
此时,似乎 test 分支已经没有存在的必要了,我们可以将它删除,使用命令 git branch-delete test 。
当然,如果我们发现在 test 分支上于不下去了,又想回到 master 分支,那么你可以直接干掉 test 分支,回归 master。
以上一整套的操作其实映射出几个问题:
(1) 不要轻易地删除分支或回滚,以及其他可能造成数据丢失的行为,三思而行(虽然在git 的体系下,并不会真正的造成丢失,后面会有一个数据拯救追回的实例);
(2) 你应该有一个主分支,比如 master 或 man,并目秉持亚肃的态度,不轻易地直接对其进行改动。并保证主分支上的代码是相对成熟的:
(3) 每开一个子分支一定要知道为什么开它,以及它的使命是什么? 原则上来说,一切子分支都应该为主分支服务。
以上振南只是对 Git 的本地化操作的一些皮毛进行了介绍,我想已经足够大家应付一般的情况了。