git 简明教程-之原理探索方法

2020/07/15

准备

创建仓库

cd /tmp
mkdir demo-repo
cd demo-repo
git init 
ls -alh # 你会发现有一个.git的文件夹,git会把你所有commit的东西都放在里面

其实这时候我们可以用 find看看.git下有写什么

.git
.git/config
.git/objects
.git/objects/pack
.git/objects/info
.git/HEAD
.git/info
.git/info/exclude
.git/description
.git/hooks
.git/hooks/commit-msg.sample
.git/hooks/pre-rebase.sample
.git/hooks/pre-commit.sample
.git/hooks/applypatch-msg.sample
.git/hooks/fsmonitor-watchman.sample
.git/hooks/pre-receive.sample
.git/hooks/prepare-commit-msg.sample
.git/hooks/post-update.sample
.git/hooks/pre-applypatch.sample
.git/hooks/pre-push.sample
.git/hooks/update.sample
.git/refs
.git/refs/heads
.git/refs/tags

创建你需要版本管理的文件

echo 'hello git!' > test.txt

OK,现在目录demo-repo下你要分清两个位置

为啥要分清呢?

  1. .git目录是所有文件版本的存储地方
  2. .git 外面则是一个临时的舞台,外面的东西丢了,被修改了,都可以在里面找回来

提交文件

git add test.txt
git commit -m 'init'

这时候我们也可以用find再看看.git下面多了写什么

.git/objects/d1
.git/objects/d1/c64694584cf480b01273f2c729fd8b6b7c320c
.git/objects/43
.git/objects/43/4d5f311d74fc724612a23e8df986544825b7aa
.git/objects/43/91316b12a31de2504617e29795dc49d22c4850

finish

OK,上面其实你已经完成了git进行版本管理的主要过程

但是。。。。。

好吧,我们在做一次修改后的提交,以体现出git版本管理

echo 'sad' > test.txt
git add .
git commit -m 'second version'

这时候我们再执行find .git命令,可以观察到.git/objects目录又有变化,这个变化有一个特点,只有增加没有删除和修改

疑问

动词:执行git commit命令

名词:上面执行的结果,自行研究objects目录

只要你不手动管理.git目录,则硬盘不坏文件永远在

其它高级的

那如何探索呢

比如文件 .git/objects/d1/c64694584cf480b01273f2c729fd8b6b7c320c

对应的object id是 d1c64694584cf480b01273f2c729fd8b6b7c320c

聪明如你,可以观察到object id其实就是d1目录名拼接上下面的文件名, 为啥我们要object id呢,因为这个文件是压缩处理后的文件,我们无法直接用cat来查看,但是git提供了相关指令git cat-file可以进行查看。

然后你可以使用 git cat-file -p d1c64694584cf480b01273f2c729fd8b6b7c320c 来看这个文件内容,是的里面的内容就是第一次commit前,test.txt文件里面的内容:

hello git!

OK,现在你可以尝试找出第二次提交test.txt文件里面的内容了。

小技巧

git clone /tmp/demo-repo/.git alpha-repo
git clone /tmp/demo-repo/.git beta-repo

OK,现在你可以用目录alpha-repo当作alpha同学本地的仓库,用目录beta-repo当作beta同学的仓库了。

git log --branches --remotes --source | grep <sha>

* 忽略已经提交的文件
    
    - 修改`.gitignore`文件
    - `git rm --cached <to ignore files>`

# or

git pull --all
git name-rev <SHA>

git branch -r --contains <SHA>

吐槽

参考

Finding what branch a Git commit came from