准备
- git 软件
- 命令行工具
- 需要的命令
git init
git add
git commit
git cat-file
创建仓库
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
下你要分清两个位置
.git
目录- 除去
.git
目录外的其它地方(现在来看,只有test.txt
文件)
为啥要分清呢?
.git
目录是所有文件版本的存储地方.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目录又有变化,这个变化有一个特点,只有增加没有删除和修改
疑问
- 什么是commit?
动词:执行git commit命令
名词:上面执行的结果,自行研究objects目录
- 我commit后的文件会丢失吗?
只要你不手动管理.git目录,则硬盘不坏文件永远在
其它高级的
- branch,这个真的很高级(自行对比svn),可以理解为指向某个commit的一条记录
- tag,同上
- 版本回退,同上
- 版本合并,这个怎么理解呢,可以简单理解成,你从其它commit上的更改和你当前commit上合并到一起(修改了
test.txt
文件),然后再重新提交 - 分布式协同管理(就是多人在多台机器上如何同步文件的增删改呢),聪明如你,可以想到,同上,只是在不同机器不同仓库之间传递commit,然后做合并罢了。
- 理解了上面,你就可以把git当作一个本地的文件版本管理工具了,在上面构建分布式的管理是轻而易举的事情。
那如何探索呢
- 主要是探索 .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目录下各个文件的关系?等等,不要再去网上查了,开动你的大脑,大胆去猜测,只要你能说通自己就OK,而不必太care别人说的。
小技巧
- 如何在本地测试多人协作呢
git clone /tmp/demo-repo/.git alpha-repo
git clone /tmp/demo-repo/.git beta-repo
OK,现在你可以用目录alpha-repo
当作alpha同学本地的仓库,用目录beta-repo
当作beta同学的仓库了。
- 查找某个commit是从哪个分支里面来的
git log --branches --remotes --source | grep <sha>
* 忽略已经提交的文件
- 修改`.gitignore`文件
- `git rm --cached <to ignore files>`
# or
git pull --all
git name-rev <SHA>
- 查看某个commit在哪些分支里面
git branch -r --contains <SHA>
吐槽
- git 为什么不在commit里面记录当前分支的信息呢。。。。
- git cat-file为啥不能直接用文件名作为入参呢。。。。