Git - 0 Linus再封神
前言
Git的内容相对较多,学习成本相对较高,要讲清楚,需要兼顾两方面, 使用和原理
.
我认为以使用为主轴,然后在适合的时候讲述原理(比如分支等特性),更容易接受.
Plan:分几篇来讲,最后用一篇文章把前面的分篇汇总.
任何零基础的人跟着我写的内容, 都能把使用跟原理学会.
任何学习最重要的是,理解理论然后结合实践
,不要死记硬背,多用就记住了.
这里推荐个网站:gitee官方的git大全.
时间不多,一本 pro git中文版 也够了,命令教程,工作流程原理图跟Git内部对象
存储原理都讲的挺详细了.
想比较完整的学git底层原理还有几本书:
《git权威指南》,《完全学会git github git server的24堂客》,《git版本控制管理》
几个网站:
图解git,猴子都能懂的git入门,B站这个up讲的内部原理,
git官网,The Git Community Book
遇到具体问题再去网上搜索,不建议看别人的博客学习.他们的博客大多写的很浅显.
0000 基础介绍
0x00 版本控制系统(VCS)
我们要介绍的Git就是一款版本控制系统(Version Control System).
版本控制系统(VCS)最基本的功能是版本控制.所谓版本控制,意思就是在文件的修改历程中保留修改历史,让你可以方便地撤销之前对文件的修改操作.
在企业中,多位工程师共同完成一个代码项目,那么各个工程师有不同的分工,那么大家如何来一同完成各自的分工,然后把代码合到一起的呢?就是靠VCS了.
同时,一个项目由于敏捷开发,或者其他维护等原因会有多个版本发布,那么这些版本之间又怎样来管理? 这也是VCS的职责.
版本控制产品非常的多(Perforce,Rational ClearCase,RCS(GNU Revision Control System),Serena Dimention,SVK,BitKeeper,Monotone,Bazaar, Mercurial,SourceGear Vault), 现在影响力最大且使用最广泛的是Git与SVN!
其中,SVN是集中式VCS的代表,而Git则开创了分布式VCS.
集中式版本控制系统介绍
所有的版本数据都保存在一个服务器上,协同开发者从服务器上同步更新或上传自己的修改.
所有的版本数据都存在服务器上,用户的本地只有自己以前所同步的版本,如果不连网的话,用户就看不到历史版本,也无法切换版本验证问题,或在不同分支工作。而且,所有数据都保存在单一的服务器 上,有很大的风险这个服务器会损坏,这样就会丢失所有的数据,当然可以定期备份。
集中式VCS下,用户A与用户B之间是无法直接通讯协作的!只能直接与中央服务器进行通讯!!
分布式版本控制系统介绍
分布式版本控制系统根本没有所谓的“中央服务器”,每个人的电脑上都是一个完整的版本库,这样你工作的时候,就不需要联网了,因为版本库就在你自己的电脑上。
既然每个人电脑上都有一个完整的版本库,那多个人如何协作呢?比方说你在自己电脑上改了文件A,你的同事也在他的电脑上改了文件A,这时,你们俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。
和集中式版本控制系统相比,分布式版本控制系统的安全性要高很多,因为每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就可以了。而集中式版本控制系统的中央服务器要是出了问题,所有人都没法干活了。
在实际使用分布式版本控制系统的时候,其实很少在两人之间的电脑上推送版本库的修改,因为可能你们俩不在一个局域网内,两台电脑互相访问不了,也可能今天你的同事病了,他的电脑压根没有开机。
因此,分布式版本控制系统通常也有一台充当"中间人"的电脑,但这个"中间人"的作用仅仅是个中间仓库,用来方便"交换"大家的修改,它不是"中央服务器",没有它大家也一样干活,只是交换修改不方便而已。
0x01 Git的诞生
在2002年以前,世界各地的志愿者把源代码文件通过diff的方式发给Linus,然后由Linus本人通过手工方式合并代码!
Linus坚定地反对CVS和SVN,这些集中式的版本控制系统不但速度慢,而且必须联网才能使用。有一些商用的版本控制系统,虽然比CVS、SVN好用,但那是付费的,和Linux的开源精神不符。
到了2002年,Linux系统已经发展了十年了,代码库之大让Linus很难继续通过手工方式管理了,社区的弟兄们也对这种方式表达了强烈不满,于是Linus选择了一个商业的版本控制系统BitKeeper,BitKeeper的东家BitMover公司出于人道主义精神,授权Linux社区免费使用这个版本控制系统。
时间到了2005年, Linux社区牛人聚集,不免沾染了一些梁山好汉的江湖习气。开发Samba的Andrew试图破解BitKeeper的协议(这么干的其实也不只他一个),被BitMover公司发现了,于是BitMover公司怒了,要收回Linux社区的免费使用权。
Linus没有另找下一家软件服务商,而是花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!一个月之内,Linux系统的源码已经由Git管理了!
之后Git以野火燎原之势成为最流行的分布式版本控制系统.尤其是2008年,Chris Wanstrath跟其他几位创始人开发的GitHub网站上线了(这又是另一个故事了),它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery,PHP,Ruby等等.
(后面涉及到远程仓库的时候,也会讲到Github.)
0001 安装与配置
0x00 安装
作为嵌入式开发者,主力肯定是在Linux环境下进行学习和作业.
(Windows系统下的安装,请百度一下,一搜一堆.或者参考官网指导.)
- OS:Ubuntu 20.04
- Terminal
apt安装命令
Ubuntu 16.04之后推荐更多的用apt命令,原因可以百度一下.
$ sudo apt install git
安装完毕之后,查看Git版本信息,有的话,说明安装成功.
$ git --version
git version 2.25.1
安装成功了.
0x01 配置
-
三个级别
配置有三个级别, 每个级别的配置文件位置也不同:
git config --system
命令
系统级配置,作用域为该计算机的所有用户创建的项目,优先级低于global
.文件位置为
/etc/gitconfig
.该命令使用频率较低.
git config --global
命令
用户级配置,作用域为当前登陆的用户创建的所有项目,常用.优先级低于local
.文件位置在
/home/用户名/.gitconfig
git config --local
命令
仓库级配置,作用域特定版本仓库,不常用,是最精确具体的,优先级最高.文件位置在项目文件夹中
的隐藏仓库文件夹.git/config
.
使用git config
查看配置相关的命令
使用git config -l
或者 git config --list
来查看所有的git配置项.
-
配置用户名与邮箱`(重要)
根据以上三级的git配置,来设置用户名与邮箱,这样后面在提交代码到仓库的时候会有用户名
与邮箱记录.不然查提交者很麻烦.
git config --global user.name "Tony"
(可以支持中文,但Linux下需要UTF-8)
git config --global user.email xxx@qq.com
设置完成后, 就可以到对应位置的配置文件中,去查看配置内容了.
$ cat /home/tony/.gitconfig
看到的是
[user]
name = Tony
email = xxx@qq.com
[core]
editor = vim
[color]
ui = true
可以进行其他配置项的更改,有需要请搜索具体的配置内容.
-
命令查看配置内容
$ git config -l
user.name=Tony
user.email=xxx@qq.com
core.editor=vim
color.ui=true
查看某一级的配置内容:
$ git config --global --list
看到的是
user.name=Tony
user.email=80725015@qq.com
core.editor=vim
color.ui=true
tony@ubuntu:~$ git config --system --list
$ git config --system --list
因为我没有配置过系统级的配置内容,所以内容就不会显示.
fatal: 无法读取配置文件 '/etc/gitconfig': 没有那个文件或目录
tony@ubuntu:~/learnGit$ git config --local --list
仓库级的配置内容,只能进入项目文件夹才能查看.
下面这些是git init之后自动生成的,未改动过.
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
查看具体配置项的内容:
tony@ubuntu:~/learnGit$ git config user.name
输出内容:Tony
tony@ubuntu:~/learnGit$ git config user.email
输出内容:xxx@qq.com
tony@ubuntu:~/learnGit$ git config color.ui
输出内容:true
tony@ubuntu:~/learnGit$ git config core.editor
输出内容:vim
-
删除config配置项
git config --级别 --unset <参数名>
or文件中删除
级别就是system,global和local 忘了吗?
先添加一个local级的user.error配置项:
tony@ubuntu:~/learnGit$ git config --local user.error '错误参数'
tony@ubuntu:~/learnGit$ git config --local --list
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
user.error=错误参数
有了.
再删除它.
tony@ubuntu:~/learnGit$ git config --local --unset user.error
tony@ubuntu:~/learnGit$ git config --local --list
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
删掉了.
如果省略了 --级别
这个参数,只能在项目文件夹下删除local级的选项.
tony@ubuntu:~$ git config --unset user.error
fatal: 不在 git 仓库中
-
.gitignore
使用.gitignore配置文件,可以在提交代码时,不提交
.gitignore配置文件中设置的文件类型.
通常用来忽略本地开发中的下列文件:
.idea
、.settings
、.classpath
等无用配置;- 系统自动生成的文件:各种
IDE
的配置文件,项目依赖文件
等;如vue-cli
创建项目中node_modules
目录下的各种依赖文件; - 编译生成的中间文件,可执行文件;
- 敏感的配置文件和本地不想提交的脚本文件等;
.gtiignore
文件非常重要,一般放在创建项目的根目录上.如/home/tony/learnGit/.gitignore
注意在.gitignore文件中一行写一个文件名;.gitignore文件也支持正则表达式比如:
*.a
:忽略所有以.a
结尾的文件;!lib.a
:表示除了lib.a
文件,其余都会被忽略;- /TODO:仅仅忽略项目
根目录
下的TODO文件,不包括subdir/TODO
(TODO
为示例文件);- 可以通过
/*/TODO
使一层目录下的TODO
文件被忽略; - 通过
/**/TODO
使所有层目录下的TODO
文件都被忽略;
- 可以通过
build/
表示忽略build
目录下的所有文件;doc/*.txt
表示忽略doc
目录下所有的.txt
文件,包括doc/notes.txt
但不包括doc/server/.arch.txt
;doc/*/*.txt
会忽略doc目录
及其任何一个子目录下的所有.txt
文件,比如doc/bin/2.txt
(/ * 表示一层目录);- 而
doc/**/*.txt
则会把doc任何一层目录及其子目录下的.txt
文件忽略;即/**/ 两颗星表示所有层目录
;
配置小技巧(懒人专用)
其实我们不需要每次都手写一遍.gitignore文件,可以通过这个网站自动生成不同语言项目的忽略文件:http://gitignore.io/
进去之后随便写个语言比如C语言,能出现一个完整的内容.
# Created by https://www.toptal.com/developers/gitignore/api/c
# Edit at https://www.toptal.com/developers/gitignore?templates=c
### C ###
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
# End of https://www.toptal.com/developers/gitignore/api/c
-
.gitignore失效
原因:.gitignore
只能忽略那些原来没有被追踪(untrack
)的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore
是无效的。
解决方案:清除git本地缓存,将文件转变为untrack
状态,然后再提交:
git rm -r --cached .
git add .
tony@ubuntu:~/learnGit$ git status
我在git安装完,配置完之后,只在一个文件夹下执行过git init,从没git add过任何文件.
只在工作区写过创建过两个文件,并且在里面编辑了些内容.
未跟踪的理解:
位于分支 master
尚无提交
未跟踪的文件:
(使用 "git add <文件>..." 以包含要提交的内容)
Firstfile.c
ReadME.md
提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)
这个链接内,就先写两个章节吧.