内容简介:记录一下Git的基础操作原理,还有Git信息泄漏在比赛中的一些问题。git init创建一个git_test文件夹,并使用git init命令初始化一个空的Git 仓库
记录一下Git的基础操作原理,还有Git信息泄漏在比赛中的一些问题。
Git基本操作
git init
创建一个git_test文件夹,并使用git init命令初始化一个空的Git 仓库
Rain@Rai4over MINGW64 ~/Desktop $ mkdir git_test Rain@Rai4over MINGW64 ~/Desktop $ cd git_test/ Rain@Rai4over MINGW64 ~/Desktop/git_test $ git init Initialized empty Git repository in C:/Users/Rain/Desktop/git_test/.git/ Rain@Rai4over MINGW64 ~/Desktop/git_test (master) $ ls -a ./ ../ .git/
git add && git commit
创建一个test1.txt文件,通过git add跟踪这个文件,然后使用git commit提交更新到仓库。
Rain@Rai4over MINGW64 ~/Desktop/git_test (master)
$ echo 'test1file haha' >test1.txt
Rain@Rai4over MINGW64 ~/Desktop/git_test (master)
$ cat test1.txt
test1file haha
Rain@Rai4over MINGW64 ~/Desktop/git_test (master)
$ git status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
test1.txt
nothing added to commit but untracked files present (use "git add" to track)
Rain@Rai4over MINGW64 ~/Desktop/git_test (master)
$ git add test1.txt
warning: LF will be replaced by CRLF in test1.txt.
The file will have its original line endings in your working directory.
Rain@Rai4over MINGW64 ~/Desktop/git_test (master)
$ git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: test1.txt
Rain@Rai4over MINGW64 ~/Desktop/git_test (master)
$ git commit -m "test1file"
[master (root-commit) 4089fd9] test1file
1 file changed, 1 insertion(+)
create mode 100644 test1.txt
Rain@Rai4over MINGW64 ~/Desktop/git_test (master)
$ git log
commit 4089fd99a9bd7ee0cec8f94ce1c66b650054080e (HEAD -> master)
Author: Rai4over <faith4444@163.com>
Date: Sun Sep 2 17:52:35 2018 +0800
test1file
查看状态 && 暂存区
git status命令可以查看仓库状态,列出当前目录所有还没有被git管理追踪的文件和被git管理且被修改但还未提交更新的文件.。
文件状态
仓库中的文件可能存在于这三种状态:
- Untracked files → 文件未被跟踪;
- Changes to be committed → 文件已暂存,这是下次提交的内容;
- Changes not staged for commit → 已跟踪文件的内容发生了变化,但还没有放到暂存区。
通过git add的文件会加入暂存区,之后git commit会将暂存区的所有文件提交更新。
Git对象和目录
Git对象
在Git系统中有四中类型的对象,所有的Git操作都是基于这四种类型的对象。
-
"blob",这种对象用来保存文件的内容。
-
"tree",可以理解成一个对象关系树,它管理一些"tree"和“blob”对象。
-
"commit",指向一个"tree",它用来标记项目某一个特定时间点的状态。它包括以下关于时间点的元数据,如时间戳、最近一次提交的作者、指向上次提交、
-
"tag",给某个提交增添一个标记。
SHA1哈希值
在Git系统中,每个Git对象都通过哈希值来代表这个对象。哈希值是通过SHA1算法计算出来的,长度为40个字符(40-digit)。
Commit 对象
commit对象一般包含以下信息:
-
代表commit的哈希值
-
指向tree对象的哈希值
-
作者
-
提交者
-
注释
Tree 对象
Tree对象一般包含以下信息:
-
代表blog的哈希值
-
指向tree对象的哈希值
Blob 对象
Blob对象一般包含用来存储文件的内容。
Tag 对象
标签对象一般包含以下信息:
- 一个对象名(SHA1签名)
- 对象类型
对象间的关系
commit、tree、blob三个对象的简单关系如下:
若仓库的目录结构如下:
|-- README
`-- lib
|-- inc
| `-- tricks.rb
`-- mylib.rb
git对象 结 构的关系图如下:
.git目录
在我们使用git init初始化git仓库的时候,会生成一个.git的隐藏目录,git会将所有的文件,目录,提交等转化为git对象,压缩存储在这个文件夹当中。
-
COMMIT_EDITMSG:保存最新的commit message,Git系统不会用到这个文件,只是给用户一个参考
-
config:这个是GIt仓库的配置文件
-
description:仓库的描述信息,主要给gitweb等git托管系统使用
-
HEAD:这个文件包含了一个档期分支(branch)的引用,通过这个文件Git可以得到下一次commit的parent
-
hooks:这个目录存放一些 shell 脚本,可以设置特定的git命令后触发相应的脚本;在搭建gitweb系统或其他
git托管系统会经常用到hook script
-
index:这个文件就是我们前面提到的暂存区(stage),是一个二进制文件
-
info:包含仓库的一些信息
-
logs:保存所有更新的引用记录
-
objects:所有的Git对象都会存放在这个目录中,对象的SHA1哈希值的前两位是文件夹名称,后38位作为对象文件名
-
refs:这个目录一般包括三个子文件夹,heads、remotes和tags,heads中的文件标识了项目中的各个分支指向的当前commit
-
ORIG_HEAD:HEAD指针的前一个状态
Git引用
Git中的引用是一个非常重要的概念,对于理解分支(branch)、HEAD指针以及reflog非常有帮助。
Git系统中的分支名、远程分支名、tag等都是指向某个commit的引用。比如master分支,origin/master远程分支,命名为V1.0.0.0的tag等都是引用,它们通过该保存某个commit的SHA1哈希值指向某个commit
HEAD也是一个引用,一般情况下间接指向你当前所在的分支的最新的commit上。HEAD跟Git中一般的引用不同,它并不包含某个commit的SHA1哈希值,而是包含当前所在的分支,所有HEAD直接执行当前所在的分支,然后间接指向当前所在分支的最新提交。
查看当前分支,当前分支为master,并通过git log可以发现这个commit就是master分支上最新的提交。
Rain@Rai4over MINGW64 ~/Desktop/git_test (master) $ git status On branch master nothing to commit, working tree clean Rain@Rai4over MINGW64 ~/Desktop/git_test (master) $ cat .git/HEAD ref: refs/heads/master Rain@Rai4over MINGW64 ~/Desktop/git_test (master) $ cat .git/refs/heads/master 29bb92d948b861d13c0912694a6000d33b62fea3 Rain@Rai4over MINGW64 ~/Desktop/git_test (master) $ git cat-file -p 29bb92d948b861d13c0912694a6000d33b62fea3 tree 57f5feedc4fa5a298d6d89aa93fd205bb588458e parent 4089fd99a9bd7ee0cec8f94ce1c66b650054080e author Rai4over <faith4444@163.com> 1535977002 +0800 committer Rai4over <faith4444@163.com> 1535977002 +0800 test2 Rain@Rai4over MINGW64 ~/Desktop/git_test (master) $ git log -n 1 commit 29bb92d948b861d13c0912694a6000d33b62fea3 (HEAD -> master, test) Author: Rai4over <faith4444@163.com> Date: Mon Sep 3 20:16:42 2018 +0800 test2
所有的内容都是环环相扣的,我们通过HEAD找到一个当前分支,然后通过当前分支的引用找到最新的commit,然后通过commit可以找到整个对象关系模型:
引用和分支
-
git branch test,创建名为test分支。
-
git checkout test,切换到test分支。
除了master分支,创建了一个test的分支,切换到新分支,查看HEAD,HEAD的指向发生了变化。
再次查看“.git/refs/heads/”目录,可以看到除了master文件之外,又多了一个test文件,查看该文件的内容也是一个哈希值。
Rain@Rai4over MINGW64 ~/Desktop/git_test (master) $ cat .git/HEAD ref: refs/heads/master Rain@Rai4over MINGW64 ~/Desktop/git_test (master) $ cat .git/refs/heads/master 29bb92d948b861d13c0912694a6000d33b62fea3 Rain@Rai4over MINGW64 ~/Desktop/git_test (master) $ git checkout test Switched to branch 'test' Rain@Rai4over MINGW64 ~/Desktop/git_test (test) $ cat .git/HEAD ref: refs/heads/test Rain@Rai4over MINGW64 ~/Desktop/git_test (test) $ cat .git/refs/heads/test 29bb92d948b861d13c0912694a6000d33b62fea3
-
git show-ref --heads,命令就可以查看所有的头
Rain@Rai4over MINGW64 ~/Desktop/git_test (master) $ git show-ref --heads 29bb92d948b861d13c0912694a6000d33b62fea3 refs/heads/master 29bb92d948b861d13c0912694a6000d33b62fea3 refs/heads/test
进入.git/logs文件夹,可以看到这个文件夹也有一个HEAD文件和refs目录,这些就是记录仓库修改的地方。
目录下记录了包括git commit,git checkout,git stash等命令的操作历史。
-
git stash,保存当前工作进度,会把暂存区和工作区的改动保存起来。
执行完这个命令后,在运行git status命令,就会发现当前是一个干净的工作区,没有任何改动。
当然可以使用git stash pop来恢复之前的进度.
Rain@Rai4over MINGW64 ~/Desktop/git_test/.git/logs (GIT_DIR!) $ ls HEAD refs/ Rain@Rai4over MINGW64 ~/Desktop/git_test/.git/logs (GIT_DIR!) $ ls refs/ heads/ stash Rain@Rai4over MINGW64 ~/Desktop/git_test/.git/logs (GIT_DIR!) $ ls refs/heads/ master test
索引index
index/stage,就是更新的暂存区,看看index文件。
index(索引)是一个存放了已 排序 的路径的二进制文件,并且每个路径都对应一个SHA1哈希值。在Git系统中,可以通过git ls-files --stage来显示index文件的内容。
创建新文件,添加到暂存区(SHA1哈希值已经改变)
$ git ls-files --stage 100644 1453b33002ce30e42459ca3ea867c2aeefe1a0fa 0 test1.txt 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 test2.txt Rain@Rai4over MINGW64 ~/Desktop/git_test (master) $ echo 333 > test3.txt Rain@Rai4over MINGW64 ~/Desktop/git_test (master) $ git ls-files --stage 100644 1453b33002ce30e42459ca3ea867c2aeefe1a0fa 0 test1.txt 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 test2.txt Rain@Rai4over MINGW64 ~/Desktop/git_test (master) $ git add test3.txt warning: LF will be replaced by CRLF in test3.txt. The file will have its original line endings in your working directory. Rain@Rai4over MINGW64 ~/Desktop/git_test (master) $ git ls-files --stage 100644 1453b33002ce30e42459ca3ea867c2aeefe1a0fa 0 test1.txt 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 test2.txt 100644 55bd0ac4c42e46cd751eb7405e12a35e61425550 0 test3.txt
对象的存储
所有的Git对象都会存放在.git/objects目录中,对象SHA1哈希值的前两位是文件夹名称,后38位作为对象文件名。
.git泄漏 | Example
我们常用的.git泄漏文件恢复 工具 有很多,但是如果不懂原理,可能会遇到恢复文件缺少的问题,因为多数工具只会恢复HEAD指针的commit对象。
这里拿某比赛的题目举个例子:
打开浏览器console发现提示,并且恢复HEAD指针的commit对象并不能得出正确源码。
获得commit
这里可以想到使用git stash,当然最稳妥的办法当然是遍历所有commit,不管是通过log,refs,HEAD等文件或目录均可,得到的commit指针都是一样的。
-
commit hash ,e5b2a2443c2b6d395d06960123142bc91123148c
-
访问commit对象,.git/objects/e5/b2a2443c2b6d395d06960123142bc91123148c
获得tree
-
根据commit对象得到tree对象的hash
-
访问tree对象,.git/objects/76/9905f5a6f425ce62ed9a1cbf375a61fb56b406
获得Blob
-
根据tree对象得到blob对象的hash
-
访问blob对象,.git/objects/8e/f569f235780f24c42b60f50d528a03f7238c80
其实只要明白了原理,不管commit的hash藏在哪里都能应对自如。
以上所述就是小编给大家介绍的《Git信息泄漏原理探究》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Android 系统开发_内存泄漏篇 -- "内存泄漏"的前世今生
- 跨域不完全探究
- Spring源码探究:容器
- Flutter BuildContext 探究
- Flutter mixins 探究
- Serverless 一些探究(一)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Data Structures and Algorithm Analysis in Java
Mark A. Weiss / Pearson / 2006-3-3 / USD 143.00
As the speed and power of computers increases, so does the need for effective programming and algorithm analysis. By approaching these skills in tandem, Mark Allen Weiss teaches readers to develop wel......一起来看看 《Data Structures and Algorithm Analysis in Java》 这本书的介绍吧!