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/TODOTODO为示例文件);
    • 可以通过/*/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" 建立跟踪)

这个链接内,就先写两个章节吧.

posted @ 2022-10-09 19:30  道阻且长行则将至Go  阅读(89)  评论(0编辑  收藏  举报