Git目录
须知
- Git是版本控制工具,版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。
- Git是 Linux 的缔造者 Linus Torvalds开发出来,
- Git采用的是直接记录快照的方式,而非差异比较。 每次你提交更新,或在 Git 中保存项目状态时,它主要对当时的全部文件制作一个快照并保存这个快照的索引。 为了高效,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。 Git 对待数据更像是一个 快照流。
状态
这里面表示版本控制中里面的文件,也就是都处于已跟踪状态
Git 有三种状态,你的文件可能处于其中之一:
- 已修改(modified):已修改表示修改了文件,但还没保存到数据库中。
- 已暂存(staged):表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。
- 已提交(committed):数据已经安全的保存在本地数据库中。
由此引入本地 Git 项目的三个工作区域的概念:工作目录(Working Directory)、暂存区域(Staging Area) 以及 Git 仓库(版本库)(.git directoty)。
- 图中左侧为工作区,右侧为版本库。在版本库中标记为 “index” 的区域是暂存区(stage, index),标记为 “master” 的是 master 分支所代表的目录树。
- 图中我们可以看出此时 “HEAD” 实际是指向 master 分支的一个"游标"。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。
- 图中的 objects 标识的区域为 Git 的对象库,实际位于 “.git/objects” 目录下,里面包含了创建的各种对象及内容。
当对工作区修改(或新增)的文件执行 “git add” 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。
当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是>提交时暂存区的目录树。
当执行 “git reset HEAD” 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。
当执行 "git rm --cached " 命令时,会直接从暂存区删除文件,工作区则不做出改变。
当执行 “git checkout .” 或者 "git checkout – " 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。
当执行 “git checkout HEAD .” 或者 "git checkout HEAD " 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。
通过对上面的理解,可以简单的描述为:
基本的 Git 工作流程如下:
- 在工作目录中修改文件。
- 暂存文件,将文件的快照放入暂存区域。
- 提交更新,找到暂存区域的文件,将快照永久性存储到 Git 仓库目录。
版本
在Git中,用HEAD表示当前版本,上一个版本就是HEAD^ ,上上一个版本就是HEAD^^ ,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。
可以通过git reflog 查看分支上的版本号.使用响应的命令进行版本控制.
操作
Git 的工作就是创建和保存你项目的快照及与之后的快照进行对比。
1.常用命令
//初始化仓库: 进入项目目录运行
git init
//从一个服务器克隆一个现有的 Git 仓库
git clone [url]
//自定义本地仓库的名字:
git clone [url] directoryname
//检测当前文件状态 :
git status
//提出更改(把它们添加到暂存区):
// (针对特定文件)
git add filename
//(所有文件)
git add *
//(支持通配符,所有 .txt 文件)
git add *.txt
//忽略文件:在文件根目录下面添加.gitignore 文件
//提交更新:
git commit -m "代码提交信息"
//跳过使用暂存区域更新的方式( git commit 加上 -a 选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤。) :
git commit -a -m "代码提交信息"
//移除文件 (从暂存区域移除,然后提交。)??????:
git rm filename
//对文件重命名 (这个命令相当于mv README.md README、git rm README.md、git add README 这三条命令的集合):
git mv README.md README
//查看提交日志(加上参数表示查看提交间的差异)
git log -p
//将本地推送到远端
git push origin
//将这些改动提交到远端仓库:
git push origin master
//将 test 重命名位 test1(远程仓库的移除与重命名):
git remote rename test test1
//移除远程仓库 test1:
git remote rm test1
//查看分支上的所有命令历史信息
git reflog
//查看提交历史
git log
2. 分支命令
新建分支
git branch test
切换分支
git checkout test
合并分支(可能会有冲突)
git merge dev
将分支推送到远端仓库
git push origin
3.拉取命令
通常使用git pull拉取远端分支上的更新,并且跟本地的文件进行合并,在git上留下记录.
git pull origin master
同时还有一种取回命令,可以获取线上的更新,但是不会出现代码合并,只是修改的文件会出现在线上.
git fetch origin master
4.合并命令
将一个分支的修改融入到另一个分支的一种方式是执行 git merge。Git 可执行两种类型的合并:fast-forward 和 no-fast-forward。
git merge dev
(1)将dev分支合并到主分支上面,这时后相对dev分支来说,master分支没有进行其他的 提交,git会进行-ff合并,直接将dev分支合并到master分支上。
(2) 很多情况下,master分支上也进行了提交,所以git会执行-no-ff合并操作,这种情况下会创建一个提交,分别指向主分支和dev分支,在这个节点上dev上面的修改都会被合并到master分支上面。
(3)发生合并就很可能会出现冲突,可以通过以下进行冲突解决
git merge dev
//出现冲突,使用以下命令
//查看冲突文件
git status
//修改冲突文件之后
git add *
git commit -m “提交名”
//提交完成之后会显示分支合并成功
5.拣选命令
可以从其他分支上面挑选一次提交复制到本分支上面,实现小范围的合并操作.
git cherry-pick 76d12(提交名)
6.变基命令
变基操作也可以称为合并操作,在有些方面可能合并的更加优雅。
git rebase master
git会将单前分支上的所有提交都复制到要master分支上面
交互式变基
实现合并的功能之外还可已实现更多的操作。
git rebase -i head~3
通过上面的命令打开提交列表,可以实现对提交进行交互式操作。
reword:修改提交信息;
edit:修改此提交;
squash:将提交融合到前一个提交中;
fixup:将提交融合到前一个提交中,不保留该提交的日志消息;
exec:在每个提交上运行我们想要 rebase 的命令;
drop:移除该提交。
通过修改前面的单词,对每次提交进行操作。
7.撤销命令
(1)补充
有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有 –amend 选项的提交命令尝试重新提交:
git commit --amend
例如,你提交后发现忘记了暂存某些需要的修改,可以像下面这样操作:
git commit -m 'initial commit'
git add forgotten_file
git commit --amend
(2)工作区撤销
取消修改
git restore <file>
(3)缓存区撤销
取消缓存
git restore --staged <file>
(4)版本库撤销
就是已提交进行撤回,可以使用很多种方式进行撤销
(1) 重置
软重置,之前提交修改的文件不会丢失,会存在暂存区
git reset --soft HEAD~2
硬重置,会将缓存区的重置到制定版本,也会将工作区的文件修改丢弃。
git reset --hard HEAD~2
(2)还原
还原是通过弥补之前的修改实现撤销的操作,会通过提交实现。也就是说会留下操作记录。
git revert ec5be(提交编号)
(3)还可以通过交互式变基实现,上面有介绍。
Git底层实现
1. Git 是一个内容寻址文件系统。
很多次意识到Git能实现数据存储.Git 的核心部分是一个简单的键值对数据库(key-value data store)。 你可以向该数据库插入任意类型的内容,它会返回一个键值,通过该键值可以在任意时刻再次检索(retrieve)该内容。
2. Git对象
Git包含三大对象,数据对象,树对象,提交对象.
一个分支可以理解为由这几个对象构成.
3. 基本对象存储流程
每次文件添加或者修改之后,使用add命令之后,文件会创建为数据对象.将这个数据对象交付给暂存区的树对象进行托管,树对象负责记录这些对象的HAS-1值,每次提交会生成一个提交对象,这个提交对象由缓存区的顶层树对象,作者信息,提交注释,提交父对象.所有的提交对象可以构建成一条链,可以通过最底层的子提交获取所有的提交信息.