目录
(一)安装与配置
(二)git托管项目(git add --all . || git commit -m "备注")
(三)git提交的原理
(四)git status
(五)git log
(六) git reset 多版本切换
直接git官网(https://git-scm.com/) 下载git的windows安装包,直接安装
安装完,得到两个工具,git gui和git bash,git gui是图形化的方式来使用git,不推荐;git bash就是用模拟linux的方式让你在命令行使用git
git --version,检查一下git的版本号
git config 命令,专门用来对git环境进行各种配置
git有三个地方放环境配置:
(1)/etc/gitconfig,对当前机器上所有的用户和git项目都生效,
使用git config --system,即可对这个配置文件进行操作,一般很少去配置这个文件,因为git的配置一般都是对某个用户和项目的范围去生效
(2)~/.gitconfig,当前用户主目录的.gitconfig文件,对当前用户有效,
使用git config --global,即可对这个配置文件进行操作 ,windows下在 C:\Users\username 下
(3)项目的.git目录下的config文件,仅仅对当前git管理的这个项目有效,
直接git config操作的就是这个文件
git config --global的意思,就是设置当前用户范围内的配置,对机器上的其他用户是无效的
git config --system,就是对当前机器上所有用户都生效
git config,就是对当前所在的git项目本身生效
配置用户名和邮箱,安装好git之后第一个事情,就是配置自己的用户名和邮箱,后面每次你提交代码的时候,都会带上你的个人信息
git config --global user.name "bema"
git config --global user.email "[email protected]"
查看所有的配置项:git config --list
查看某个配置项: git config user.name
帮助文档: git add --help
- git init,初步让git准备托管我们的代码,创建了一个.git目录,是git用来存放版本数据的
- git add和git commit两个命令,完成了第一个版本的提交,代码提交到了git中,之后所有这些代码文件的变动,都会由git来管理版本
- 每次我们修改完一块代码,就可以用git add和git commit命令,将修改后的最新版本的代码提交到git中
- 循环往复,通过每次修改代码+提交修改后的代码到git中,git就完成了对我们的每个代码文件的每个版本的数据的存储,.git目录中
- 接下来,git才能为我们提供各种版本控制的功能
git项目有3个主要的部分组成:工作区(working directory / working tree),暂存区(staging area),版本库(git directory / repository)
working directory / working tree:工作区,保存的是一个项目当前的一个版本对应的所有文件,这些文件是从git版本库中的压缩后的数据库中提取出来,然后放到我们的磁盘上去。
staging area:暂存区,就是一个文件,包含在git版本库中,主要是保存了下一次要提交到的那些文件信息。在git中,对暂存区有另外一个名称,叫做index,也就是索引。
git directory / repository:git版本库,git用于存储自己的元数据,以及文档数据库的地方,默认就是在项目的.git隐藏目录中
- 首先会在工作区修改某个版本的文件
- 将某些修改后的文件放入git暂存区中,准备下一次提交到git版本库中去
- 执行一个提交操作,将暂存区中的文件保作为一个快照保存到git版本库中去
如果一个文件,已经有一个版本被保存到了版本库,那么就是committed状态;
如果这个文件被修改了,同时被加入了暂存区,那么就是staged状态;
如果这个文件修改了,还没有加入暂存区,那么就是modified状态。
所谓的工作区,指的就是当前你的git管理的项目,在本地的那个目录,也就是你能直接看到,编辑的那个目录,这就是工作区。
Git有很多特有的机制,都是跟普通的版本控制系统不一样的
(1)快照机制
普通的版本控制系统,比如说CVS,SVN等,是通过一开始提交一个原始文件,然后后面每次对文件进行修改之后再次提交,都维护这次提交对应的一个差异,通过维护每个版本的差异,就可以通过应用差异,或者回退差异,来前进或者后退文件的版本。
Git用的不是这种维护每次提交的差异,而是用的快照。每次提交文件,都是保存一份这个文件当前这个状态的一个完整快照,同时对这次提交维护一个指针,指向这个文件快照。
(2)本地化操作
大多数的git版本控制操作,只要在本地执行即可,所有的版本文件都在本地,因此操作是非常快速的。相比较于那些依赖网络的集中式版本控制系统来说,他们的大多数操作要依赖网络,速度是很慢的。
比如说通过git查看提交历史,比较历史文件的差异,都可以在本地完成,不需要通过服务器做任何事情。
如果我们在飞机或者或者上,没有网;或者在家里,没有。都没有问题,随便做开发、写代码,提交代码,在本地就可以了,等有网络的时候,再把提交的版本推送到远程服务器上去。但是SVN之类的,就不可以提交了,因为没有网,没法连接到服务器。
(3)完整性保证
git在存储任何文件之前,都会对其执行一个校验和,然后用校验和指向那个文件。这是git内核保证的,这样我们是不可以手工修改git版本库中的任何文件的,因为修改了文件之后,会导致计算出来的校验和与之前保存的校验和不匹配,文件会破损。
git用的是SHA-1 hash算法来计算校验和,这是一个40位的字符串,基于文件的内容计算出来的,看起来大概是这样的:
24b9da6552252987aa493b52f8696cd6d3b00373
如果手动破坏.git中存储的文件的内容,git会不承认,因为内容变化之后,会导致内容计算出来的SHA-1 40位的hash值变化,跟之前存储的hash值不同,就认为文件破损
(4)仅仅添加数据
git通常来说,仅仅会在自己的数据库中添加数据,因此提交文件到git之后,很少会丢失,而且如果我们定期提交文件到远程服务器,就更少丢失。
提交状态:我们的文件已经安全的保存在git的本地数据库中了。
修改状态:我们修改了文件,但是还没有提交到git的数据库中去。
暂存状态:将修改后的文件标记为即将通过下一次提交,保存到git数据库中去。
(1)新文件刚创建:untracked,此时仅仅停留在工作区中
(2)git add 新文件:new file,此时已经被追踪了,放入了暂存区中 => staged
(3)git commit 新文件:committed,已经被追踪了,放入了git仓库中 => committed
(4)修改那个文件:modified,changes not staged to be committed,没有加入暂存区,被修改的内容仅仅停留在工作区中 => modified
(5)git add 修改文件:modified,changes to be committed,修改的文件版本被已经加入暂存区 => staged
(6)git commit 修改文件:committed,修改后的新版本提交到了git仓库中 => committed
在我们提交了很多次之后,可以查看提交历史,使用git log命令即可,可以看到每次commit的信息,
包括了commit的SHA-1、作者、日期、提交说明。
包含了一个commit的SHA-1 hash值,40位的字符;
作者,从之前安装好git之后做的设置来的;
date;
提交备注
git里面,git init之后,默认初始就创建一个分支,master分支
HEAD,指针,指向了我们当前所处的分支,因为当前我们默认就处于master分支上,所以HEAD指针就是指向master的
git log --patch -2,
--patch可以显示每次提交之间的diff,
同时-n可以指定显示最近几个commit。这个是很有用的,可以看最近两次commit之间的代码差异,进行code review是比较方便的。
用git log --stat,可以显示每次commit的统计信息,包括修改了几个文件,有多少行插入,多少行删除。
用git log --pretty=oneline,可以每个commit显示一行,就是一个commit SHA-1和一个提交说明。用git log --pretty=format:"%h - %an, %ar : %s",可以显示短hash、作者、多长时间以前、提交说明。
用git log --oneline --abbrev-commit --graph,
这是最有用的,可以看到整个commit树结构,包括如何合并的,就显示每个commit的SHA-1和提交说明,同时SHA-1显示短值。
--oneline:显示一行,不要显示多行那么多东西,一行里,就显示commit的标识符,SHA-1 hash值,40位的;提交备注;显示分支和HEAD指向哪个commit
--abbrev-commit:commit的标识符,每一次commit,都有一个唯一的标识符,就是一个SHA-1 hash值,40位,显示一个短值,默认显示前7位,就是说前7位就可以唯一定位这个commit了,不需要完整的40位
--graph:显示图形化的commit历史,这个大家后面学习到分支那里就知道了,如果有分支的话,commit历史会形成一棵树的形状,这个时候用--graph可以看清楚这颗commit树长什么样子,很有的
工作区和版本库是两个分离的区域
在工作区修改代码之后,执行git add命令,会将代码放入版本库中的暂存区;
接着执行git commit命令之后,会将暂存区中的代码提交到版本库中的master分支上,而HEAD指针就指向master分支的最新一次提交。
所以现在我们就很清楚了,git add,其实就是可以多次修改代码,多次git add,然后将每次修改的代码,都放入暂存区中;
而git commit,就是一次性将暂存区中的代码,全部提交到master分支上,master分支会出现一个最新的commit,也就是一个最新的代码版本;
而HEAD作为一个指针,永远指向master分支的最新一次commit的代码版本。
HEAD^,代表了什么?
HEAD -> master -> commit(add methods for classes)
HEAD^,代表的是commit(add methods for classes)的上一个commit(add two files)
git最核心的原理
(1)三个区域:工作区、暂存区、仓库
(2)提交历史:在仓库中,blob->tree->commit->master-HEAD,这套东西形成了git的数据结构