学习git
记得刚开始的时候学习git总是不得要领,知道了git pull,git push 为啥有时候加origin 有时候不加呢 git为啥要这么弄呢
上网找也没啥好文章,其实很多IT类的好文章都是英文写的。找了几篇英文教程,写代码做实验弄明白了 —— git如此简洁简单,讲的却如此复杂,要脸吗?
现在假如我们来设计一个代码版本管理系统。 要利用一个组件,这个组件呢就是能根据文件的内容哈希值 存储和检索
版本管理往外提供什么功能呢?文件变化追踪,版本控制,分支管理(各种分支,分支合并)
别想复杂了,简洁,怎么简单怎么来,先按最简单暴力的来
文件结构就是一个树,每次提交一个树
每次提交树根连着上次提交进去的树根,那么如果这次提交有的文件没有改动怎么办呢?
那么指向上一个文件的存储节点就行了吧。
哎,这样看来树根就是一条线,这就是主干(master)了,再有分支呢
树根线分出去就行了
分支要是合并回来呢?
对呀,这里有一个算法的,这个算法要保证树的合并形态的一致性。
比如说我这里有两个分支A,B,你那里有一样的两个A,B,我这里A合并到B,然后添加一个文件c,提交。你那里B合并到A,添加c,然后在合并到A,要保证A的形态一致性。我push到server的时候,你pull下来不用update。
一下是测试代码,探测一下git底层的存储结构。
mkdir test1 && cd test1
alias zpipe="perl -MCompress::Zlib -e 'undef $/; print uncompress(<>)'"
echo Hi>1.txt
git init
git add 1.txt
original_gf=`find .git/objects/ -type f`
echo ${original_gf} # .git/objects/b1/4df6442ea5a1b382985a6549b85d435376c351
cat ${original_gf} | zpipe # blob 3Hi
echo .
git commit -m "init"
cd .git/objects
ll `find -type f`
-r--r--r-- 1 xujiazhe xujiazhe 125 12月 26 23:41 ./b0/05922db7cc03fac1dc7b60b4ed33b98711469d
-r--r--r-- 1 xujiazhe xujiazhe 18 12月 26 23:40 ./b1/4df6442ea5a1b382985a6549b85d435376c351
-r--r--r-- 1 xujiazhe xujiazhe 50 12月 26 23:41 ./d1/90eda3a45fd0d1682ff5bd94ece3cc5ab1ce25
for f in `find -type f`;
do
echo $f;
git cat-file -p ${f:2:2}${f:5}
cat $f | zpipe;
done
./b0/05922db7cc03fac1dc7b60b4ed33b98711469d
tree d190eda3a45fd0d1682ff5bd94ece3cc5ab1ce25
author jader.xu <jiazhe.cpp@gmail.com> 1388072508 +0800
committer jader.xu <jiazhe.cpp@gmail.com> 1388072508 +0800
init
commit 167tree d190eda3a45fd0d1682ff5bd94ece3cc5ab1ce25
author jader.xu <jiazhe.cpp@gmail.com> 1388072508 +0800
committer jader.xu <jiazhe.cpp@gmail.com> 1388072508 +0800
init
./b1/4df6442ea5a1b382985a6549b85d435376c351
Hi
blob 3Hi
./d1/90eda3a45fd0d1682ff5bd94ece3cc5ab1ce25
100644 blob b14df6442ea5a1b382985a6549b85d435376c351 1.txt
tree 33100644 1.txt�M�D.�����ZeI�]CSv�Q
$ cat .git/HEAD
ref: refs/heads/master
#切换分支时,HEAD会更新:
$ git checkout -b dev
$ cat .git/HEAD
ref: refs/heads/dev
弄完原理看看 这些 用法挺好的