Git的几个重要概念
来源:互联网 发布:打字软件赚钱平台 编辑:程序博客网 时间:2024/04/30 03:00
<> repository & workspace
repository, 仓库, 包含了所有的代码, 分支, 代码历史等信息.
workspace, 工作区, 从repository check out出来的代码.
git和CVS,SVN最大的不同就在于仓库的位置, CVS,SVN的仓库都是在服务器上, 代码提交, branch, tag等操作都是在服务器上完成; 相反, git的每个用户都有一份完整的repository, 也就是说, clone下来的repository和服务器上的repository是一样的. 每个人都可以是一个服务器. 这就是所谓的分布式版本控制系统.
正因为repository在本地, 所以几乎所有操作都可以本地进行, (e.g. branch, Commit, log, status ...), 只有你想和别人交换信息的时候才需要联网. 另外一个好处是速度, 所有的操作都在本地, 所以git的速度堪称飞快.
repository放置在顶层目录的.git目录下.
<> hash.
进入.git/objects/中就能看到一大堆的16进制字符组成的文件名. 所有的代码, 所有的目录, 所有的分支, 所有的变更历史... 所有的和代码相关的信息都在这些文件里. 这些Objects有3类: Blob, Tree, Commit. 所有存储到objects下的文件都会被计算SHA1值, 然后以该SHA1值作为文件名, 而它原来的文件名则存放在下面要说到"Tree"里面.
<> Blob
BLOB用来存储常规文件. 这个概念很简单, 把一个文件拷贝到object目录下, 重命名, 新的名字就是它的SHA1值. 需要注意是: 当一个文件的内容修改了, 它会以一个新的SHA1名字, 整个的重新存储到git库中, 而不单单是修改了部分. 这是git一个重要的特征, 虽然会带来一些存储上的浪费, 但是换来的很多其他方面的好处.
<> Tree
Tree用来表示目录, 存储的是一个 "文件名<-->SHA1文件名" 的列表. 根据上面的规则可以推出以下的重要结论:
* 只要某个文件/目录发生了变化, 所有的上级目录的Tree都要变化.
* 一个顶级目录的Tree, 代表了一个代码库的版本.
<> Commit
一个Commit包含一次代码的变更信息, 每git commit一次代码, 生成一个Commit. 除了log, Commiter等信息, Commit包含的最重要的信息就是两个top Tree的SHA1名称. 一个是perant Tree, 一个是current Tree. 比较这两个Tree之间的不同就能知道这个Commit包含的变更内容.
<> refs
在.git/refs目录下有很多reference, 查看这些reference的内容, 你会发现都是SHA1值. 很简单, refs就是指向某个Commit的指针. branch是refs, tag是refs, HEAD也是ref.
随着你的pull, push, Commit, branch等操作, git会自动修改这些refs.
<> stage
在git库和workspace之间还有一个index(stage), 可以把它看做是临时的中转仓库, 在代码真正放入仓库前, 先集中放在这里. 在用git status 和 git diff的时候对这个概念最有体会.
<> remote
打开.git/config, 就明白remote是什么了.
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = git://git.xxx.org/xxx.git
fetch 字段用来说明远端git库中refs和本地refs的对应关系.
url 字段是远端git库的地址.
remote通常只有一个, origin, 指向你clone的来源, 但也可以有很多个, 比如你和甲乙丙丁都做同一个项目, 那么你可以把他们都加到remote里面, 这样能fetch他们的任何一个人的改动.
<> pack
其实就是把objects压缩打包, 在git fetch/pull/push/clone中就要用到. git gc也用来减少磁盘空间的占用量.
把上面的概念精简一下:
file ==hash==> Blob
目录信息(文件列表) ==hash==> Tree
牵一发动全身, new Tree of top dir === Commit
指向Commit的指针 === refs
在这中转, 再搬到仓库区 === stage
其他仓库的位置 ==> remotes
打包 ==> pack
示例
用以上的概念可以解释所有的git操作, 先用git diff作为例子吧.
git diff master dev
这个命令用来比较master分支(主分支) 和dev分支的不同.
git内部的流程如下:
通过.git/refs/heads/master得到该分支最新的Commit:
比如:602088ec1f420f19e0c8f76715d7c035f8383f9f
可以用git show 来查看Commit的详细信息.
也可以用git ls-Tree来查看该Commit包含的目录信息.
同理得到dev分支的Commit,
对比Commit中包含的Tree, 由于SHA1相同的objects内容一定相同. 所以只需要对比SHA1不同的objects.
如果objects是Tree, 递归比较.
如果是Blob, diff 之.
输出结果
- Git的几个重要概念
- 十、Git的几个重要概念
- 几个重要的概念
- 几个重要的概念
- lucene的几个重要概念
- WPF重要的几个概念:
- 指针的几个重要概念
- C++重要的几个概念
- 算法里面的几个重要的概念
- Java多线程的几个重要概念
- 介绍J2ME的几个重要概念
- UML建模的几个重要概念
- 介绍J2ME的几个重要概念
- 面向对象的几个重要概念
- HTTP协议的几个重要概念
- HTTP协议的几个重要概念
- HTTP协议的几个重要概念
- HTTP协议的几个重要概念
- 每个人背后都会有人在默默注视着你,所以很幸福
- Flash Builder4.5切换语言
- 自驾游注意随身携带
- 关于空数组,非常有意思!
- Navicat for Mysql 10.x 注册码收藏
- Git的几个重要概念
- Windows 不能在 本地计算机 启动 SQL Server 服务 错误代码126
- Windows 7 SP1无法安装oracle10g 11g的解决办法
- 存储和数据研究领域研究调研
- CentOS5下SQLPlus方向键无法使用
- onbeforeunload与a标签在IE中的冲突bug
- TROUBLE SHOOTING: OWSM PolicyManagerException: WSM-02120 [Possible Cause : Destination unreachable]
- 预计算MV基表为远程表的快速刷新-测试
- Shell 脚本1 -- 查看今天更新/创建的文件