git基础知识
git的基础概念
模式
对于大多数版本控制软件是基于 差异 进行控制的,即在不同版本间记录的是文本的 变化,版本切换时候根据 delta 进行前进和后退。
而 Git 采用快照的方式,对每个版本记录全部文件的快照并建立索引。这样在 版本/分支 切换时候的速度就很快(无需 delta-based 模式下的线性遍历)。并且快照是以行为单位diff的,所以对于二进制文件,Git就相对较差。
基本状态 & 文件组织
版本控制其实就是对文件的版本进行控制(如修改、提交等等操作)。而由 git 进行管理的文件有几种状态:
Untracked:未跟踪,此文件在文件夹中,但并没有加入到git库,不参与版本控制。可以通过git add命令,使状态变为Staged。Unmodify:文件已经入库, 但未修改, 即版本库中的文件快照内容与文件夹中完全一致.。这种类型的文件有两种去处, 如果它被修改, 而变为Modified. 如果使用git rm移出版本库, 则成为Untracked文件;Modified: 文件已修改, 仅仅是修改, 并没有进行其他的操作。这个文件也有两个去处, 通过git add可进入暂存staged状态, 使用git checkout则丢弃修改并返回到unmodify状态, 这个git checkout即从库中取出文件, 覆盖当前修改 !Staged: 暂存状态. 执行git commit则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为Unmodify状态. 执行git reset HEAD filename取消暂存, 文件状态为Modified

而在磁盘上,版本控制状态则是以文件的形式存在,即通过文件的方式对工作空间与git仓库进行组织:

其中,
Directory:使用Git管理的一个目录,也就是一个仓库,包含我们的工作空间和Git的管理空间。WorkSpace:需要通过Git进行版本控制的目录和文件,这些目录和文件组成了工作空间。.git:存放Git管理信息的目录,初始化仓库的时候会自动创建。Index/Stage:暂存区,或者叫待提交更新区,在提交进入repo之前,我们可以把所有的更新放在暂存区。Local Repo:本地仓库,一个存放在本地的版本库;HEAD分支是指向当前的开发分支(branch)。Stash:隐藏,是一个工作状态保存栈,用于保存/恢复WorkSpace中的临时状态。这个主要是不想提交当前分支,但是又想切换到其他分支,那么通过stash保存分支未提交的临时状态。
工作空间
Git本地有三个工作区域:
- 工作目录(
Working Directory) - 暂存区(
Stage/Index) - 历史资源库(
Repository或Git Directory) 
再加上远程的git仓库(Remote Directory)就可以分为四个工作区域。文件在这四个区域之间的工作 原理/流程 可以表示为:

分支相关基本概念
在分支中,存在一些常见的分支,如:
main: 默认主分支origin: 默认远程仓库HEAD: 指向当前分支的指针HEAD^: 指向当前分支的上一个提交版本HEAD~4: 指向当前分支的上4个提交版本
特殊文件
在使用 Git 的时候,需要配合一些特殊文件来进行管理,如:
.git:Git仓库的元数据和对象数据库.gitignore:忽略文件,不需要提交到仓库的文件.gitattributes:指定文件的属性,比如换行符啥的.gitkeep:使空目录被提交到仓库(默认空目录是不会被提交到仓库的).gitmodules:记录子模块的信息.gitconfig:记录仓库的配置信息
.gitconfig 文件
在项目的中 .gitconfig 文件用于记录哪些文件不需要添加到Git版本管理中(.gitignore文件生效的前提是该文件不能是已经被添加到Git版本库中的文件)。其使用的匹配规则是blob模式匹配,具体可以参考:Git - gitignore Documentation
文件 .gitignore 的格式规范如下:
- 所有空行或者以 
#开头的行都会被Git忽略。 - 可以使用标准的 
glob模式匹配,它会递归地应用在整个工作区中。 - 若规则以 
/结束,则会匹配项目中所有同名目录下的内容,但不匹配同名文件; - 若规则以 
/开始,则会从项目根目录开始匹配; - 若规则不包含 
/,会对.gitignore同路径下的文件和目录进行屏蔽; *匹配除了/以外的任意字符串,**匹配完整路径名;?匹配除了/以外的任意单个字符;- 要忽略指定模式以外的文件或目录,可以在模式前加上叹号(
!)取反。 - 不能识别中文,因为默认编码是 GBK。
 
等等。这里显示一个常见的.gitignore 文件:
1  |  | 
使用 Git
在Git 官网中有很多对于Git的介绍,这里只记录常用的内容。
GUI可视化
对于初学者而言,在了解了Git的组织结构以及基本概念后就是需要实际操作。使用可视化工具可以明显看出每次提交的改动,这里推荐使用GitKraken, 个人感觉整个分支操作可视化会比较友好。除此之外,还有很多。但是推荐在入门之后放弃GUI并尝试命令行。
命令行
直接用cmd 或者 bash 即可。在使用Git时候直接用 git --help 查看用法即可:
1  |  | 
有啥不会直接查。
遇到问题记录
Ubuntu中设置Git提示英文
在个人电脑Ubuntu系统中使用中文导致安装git显示也为中文了。但是只想对git 命令改为显示英文,可以借助环境变量LANGUAGE和 Ubuntu系统中的alias来实现,过程如下:
尝试在命令前手动指定所有语言变量:如果输出变为英文,说明别名设置正确后即可生效。
1  |  | 
发现,对于语言而言只是LANGUAGE变量有用。即:
1  |  | 
所以,Git显示英语依赖 LANGUAGE变量,因此使用命令之前显式设置LANGUAGE变量。可以起一个别名,并且写入到配置文件(~/.bashrc)中:
1  |  | 
git下载大文件内容超时
需要配置(超时时间设置,大文件下载设置。参考:关于 GitHub 上的大文件 - GitHub 文档):
http.lowSpeedLimit:设置HTTP传输的最低速度限制(字节/秒),0 表示不限制最低速度,即Git不会因为速度过慢而中断连接。默认行为:如果未设置,Git可能会在低速连接时终止HTTP传输。http.lowSpeedTime:设置Git允许低速传输的最长时间(秒)。只有当http.lowSpeedLimit非零时,这个参数才会生效。默认行为:Git默认可能会在 30 秒(或更短)内终止低速连接。http.postBuffer:设置Git通过HTTP发送的最大数据缓冲区大小。默认值为1MB(1048576字节);设置大值适用于推送大文件或大仓库的情况。
1  |  | 
git在ssh鉴权时私钥文件权限太开放问题
在Linux系统中通过拷贝id_rsa和id_rsa.pub两个文件来登录时候,可能会由于私钥文件权限太高而提示:
1  |  | 
就是因为/root/.ssh/id_rsa的默认SSH 私钥文件的权限设置过于开放,存在安全隐患。SSH要求私钥文件必须仅对所有者可读写,其他用户不可访问。(如果使用非root账户,将/root/.ssh替换为~/.ssh),解决方案就是将权限设置为600即可:
1  |  |