在使用git的过程中经常会遇到这样的情况:
执行指令 git fetch 定住不动,以为程序死了或是网络问题。
今天我在公司又碰到了这样的情况,以为网络端口被封了。但是后来通过尝试发现网络是通的。遂静下心来分析这个问题,并对git中的远程分支和数据的管理方式上有了更深的理解。
一般我们在添加一个远程分支就是使用git remote add。这个命令执行的很快,并在git remote add之后可以在git remote show中看到你所添加的remote。
这个命令之所以运行的很快,因为git remote add仅仅修改了.git/config文件而已,在我的git测试库中是这样的:
- [remote "origin"]
-
fetch = +refs/heads/*:refs/remotes/origin/*
-
url = /home/tekkaman/development/research/git/test1
可以看出,git remote add仅仅添加了remote的URL和相关“书签”的存放目录(但是这些目录根本没有建立)
之后我们可以用git remote show看到远程库的信息,但是这个命令就执行的比较慢了,因为git remote show会获取.git/config文件中的URL,通过相关协议到网上去获取这个remote的相关分支数据,然后显示出来。 git remote show 是必须联网的,他没有本地的资料(从上面的文件中根本得不到怎么多的数据)。所有可以这么说:如果 git remote show 成功了,网络应该就是通的,进一步的git fetch应该也是可以获取到数据的。
此时我用Ti的u-boot仓库做下测试,请注意红色的部分:
- $ git remote show origin
-
* remote origin
-
Fetch URL:
-
Push URL:
-
HEAD branch: master
-
Remote branches:
-
OMAPPSP_03.00.00.05 new (next fetch will store in remotes/origin)
-
OMAPPSP_03.00.01.06 new (next fetch will store in remotes/origin)
-
OMAPPSP_03.00.02.07 new (next fetch will store in remotes/origin)
-
denx/master new (next fetch will store in remotes/origin)
-
master new (next fetch will store in remotes/origin)
-
qb_v2010.06_OMAPPSP_04.02.00.07 new (next fetch will store in remotes/origin)
-
ti816x-master new (next fetch will store in remotes/origin)
-
ti81xx-master new (next fetch will store in remotes/origin)
-
Local refs configured for 'git push':
-
master pushes to master (up to date)
-
ti816x-master pushes to ti816x-master (up to date)
-
- $ git branch -av
-
* master ae5aaeb For OMAP36xx move sys_clk to 26MHz
-
ti816x-master 38ba90d TI81XX: NAND: Setting 1-bit Hamming code H/W ECC as default ECC scheme.
也就是 git remote show origin可以查到分支,但是git branch -av却什么也看不到,因为remote命令通过网络获取了信息,而git branch 获取的是本地的数据,而现在本地什么都没有(除了.git/config中的)。
从remote的信息可以看出“下个一fetch将会将会把分支信息保存在remotes/origin”。也就是说现在没有分支信息的。
所以我们现在可以用git fetch origin看看.git目录会有什么变化:
在.git/logs/remotes/***下有了相关分支的的信息
在.git/refs/remotes/***下也有了相关分支的信息
现在git branch -av就有了相关远程分支数据信息了。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
进一步来说:
假设上面的情况下我本地的.git/objects中已经有了所有的数据,那也是需要git fetch来获取信息的,但是获取的速度会快很多,因为只需要分支信息就好了,无需下载相关的实际commit、tree、blob数据。
fetch获取的是两种数据:文件数据(commit、tree、blob)、分支信息数据(其实也是可以是版本数据等等)
所有我从中剖析出git的一些工作原理,这属于个人理解:
git数据主要分成:
仓库数据(commit、tree、blob),用于保存文件数据、数据目录结构、提交信息和之间的关联。 这些数据可以形成完整的类似树形的结构,但是我们并不知道各分支的名字,某个commit点是什么版本的(tag)等等这些信息
指针文件:这些文件记录了各个分支的最后那个commit点是哪个。tag本质上也是这样一些指向特定commit点的指针文件(尽管一些tag是有自己的commit点的)。
远程分支和本地分支的区别在于:你可以用git工具去修改本地分支所指向的commit点,但是git不允许你本地修改远程分支所指向的commit点。远程分支只由联网时通过远程服务器的信息来确定。
当然你暴力修改远程分支文件信息也是可以的,但没有任何意义~~~~下次联网还会自动校正的
阅读(742) | 评论(0) | 转发(0) |