git基础教程(27)远程仓库与git fetch
Posted 奇妙之二进制
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了git基础教程(27)远程仓库与git fetch相关的知识,希望对你有一定的参考价值。
远程仓库是指托管在因特网或其他网络(比如局域网)中的版本库。 你可以有好几个远程仓库,通常有些仓库对你只读,有些则对你可读可写。 与他人协作涉及管理远程仓库以及根据需要推送或拉取数据。
查看远程仓库
如果想查看你已经配置的远程仓库服务器,可以运行 git remote 命令。它会列出你指定的每一个远程服务器的简写。 如果你已经克隆了仓库,那么至少应该能看到 origin -—— 这是 Git 给你起的克隆的仓库服务器的默认名字:
$ git remote
origin
1
2
你也可以指定选项 -v,会显示远程仓库对应的简写和它的 URL。
$ git remote -v
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)
1
2
3
上面的命令表示,当前只有一台远程主机,叫做 origin,它的网址是https://github.com/schacon/ticgit
fetch 和 push 对应的都是这个网址,当然,也可以对应不同的网址。
如果你的远程仓库不止一个,该命令会将它们全部列出。 例如:
$ git remote -v
bakkdoor https://github.com/bakkdoor/grit (fetch)
bakkdoor https://github.com/bakkdoor/grit (push)
cho45 https://github.com/cho45/grit (fetch)
cho45 https://github.com/cho45/grit (push)
defunkt https://github.com/defunkt/grit (fetch)
defunkt https://github.com/defunkt/grit (push)
koke git://github.com/koke/grit.git (fetch)
koke git://github.com/koke/grit.git (push)
origin git@github.com:mojombo/grit.git (fetch)
origin git@github.com:mojombo/grit.git (push)
1
2
3
4
5
6
7
8
9
10
11
可以看到,一共有5个远程仓库。注意到这些远程仓库使用了不同的协议(从地址的格式就可以看出来)。
添加远程仓库
运行 git remote add 添加一个新的远程仓库,同时指定一个简写:
$ git remote
origin
$
$ git remote add pb https://github.com/paulboone/ticgit
$
$ git remote -v
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)
pb https://github.com/paulboone/ticgit (fetch)
pb https://github.com/paulboone/ticgit (push)
1
2
3
4
5
6
7
8
9
10
现在你可以在命令行中使用字符串 pb 来代替整个 URL (即https://github.com/paulboone/ticgit)。
git fetch命令
要从远程仓库中获得数据,可以执行:
$ git fetch [remote-name]
1
这个命令会访问远程仓库,从中取回所有你还没有的数据。 执行完成后,你将会拥有那个远程仓库中所有分支的引用,可以随时合并或查看。
如果你使用 clone 命令克隆了一个仓库,那么 Git 会自动将其添加为远程仓库并默认以 “origin” 为简写。 所以,git fetch origin 会抓取克隆(或上一次抓取)后新推送的所有工作。
必须注意 :git fetch 命令仅仅是将数据拉取到你的本地仓库,它并不会自动合并或修改你当前的工作。当准备好时你必须手动合并。
如果你觉得上面的文字让你云里雾里,那么请看下文。
假设服务器上有一个版本库:
最近的 2 次提交标记为 A 和 B。
这时候,你把这个版本库克隆到了本地:
克隆之后:
原始版本库中的所有提交都复制到克隆版本库。
克隆版本库中有一个名为 origin/master的远程追踪分支( remote-tracking branch),它指向原始版本库中 master 指向的提交,也就是 B。
克隆版本库中创建了一个新的本地追踪分支( local-tracking development branches),称为 master 分支。这个 master 分支指向 origin/master指向的提交,也就是 B。
克隆后,Git 会选择新的 master 分支作为当前分支,并自动检出它。因此,除非切换分支,否则克隆后所做的任何修改都会影响 master 分支。
在图中,原始版本库和派生的克隆版本库中的开发分支都由深灰色作为背景色,而远程追踪分支则用浅灰色作为背景色。在 Git 的实现中,深灰色背景的分支属于 refs/heads/ 命名空间,浅灰色背景的分支的属于refs/remotes/命名空间。
请注意,本地追踪分支和远程追踪分支都是私有的,并只存在于各自的版本库中。
远程追踪分支是远程分支状态的引用。它们是你不能移动的本地引用,当你做任何网络通信操作时,它们会自动移动。远程追踪分支像是你上次连接到远程仓库时,那些分支所处状态的书签。例如,如果你想要看你最后一次与远程仓库 origin 通信时 master 分支的状态,你可以查看 origin/master 分支。
在本地 master分支工作的时候,本地的 master 会向前移动,而origin/master是不可以移动的。正如下图所示,你的开发使 master 分支变长了:在提交 B 的基础上多出 2 个新的提交 —— X 和 Y。
在你开发期间,如果原始版本库没有任何变化,那么你可以很容易地把 X 和 Y 推送到上游:Git 会把你的提交传输到原始版本库,并把它们添加到 B 的后边,然后 Git 会把你的提交合并到原始版本库的 master 分支,实际上这是一种特殊的合并操作 —— 快进(fast-forward),快进本质上是一个简单的线性历史记录推进操作。
如下图所示:
正如前文所述,在推送(push)的过程中,本地仓库与远程仓库 origin 进行了“通信”, origin/master 分支会和远程仓库的 master 保持同步,所以,你的origin/master 分支也指向了 Y。
以上的举例是理想情况。实际情况是,在你开发期间,任何其他有权访问原始版本库的开发人员可能已经做了进一步开发,并把她的修改推送到该版本库。如下图:
在这种情况下,我们说版本库的历史记录在提交 B 处分叉(diverged 或 forked)了。当你尝试推送,Git 会拒绝它并用一条如下所示的消息告诉你有关的冲突。
$ git push
To /tmp/Depot/public_html
! [rejected] master -> master (non-fast forward)
error: failed to push some refs to ‘/tmp/Depot/public_html’
1
2
3
4
那么,什么是你真正想要做的?你想覆盖其他人员的工作,还是想要合并两组历史记录?
提示
如果你想覆盖所有其他变化,也是可以的。只要在你的 git push 中使用 -f选项即可。不过我建议你不要这么做,否则你的伙伴会恨你的……
更多的时候,你不想覆盖别人的提交,你只是想添加你自己的修改。在这种情况下,你必须在推送之前在你的版本库中合并两组历史记录。这时候,就该 fetch大显身手了。
要让 Git 合并两组历史记录,那么这两组历史记录必须存在于同一个版本库。现在你的 X 和 Y 提交本身就在你的版本库里,为了把 origin 中的 C 和 D 提交纳入你的版本库,你可以用 git fetch命令进行抓取。这个命令会访问远程仓库,从中拉取所有你还没有的数据,如下图:
注意,引入 C 和 D 这组历史记录并不能改变由 X 和 Y 代表的历史记录,所以你不用担心 fetch 操作会破坏你的劳动成果。fetch 后,这两组历史记录同时存在于你的版本库中,形成一幅比较复杂的图,简单来说就是在 B 处分叉了。你的历史记录由 master 分支代表,远程历史记录则由 origin/master 远程追踪分支代表。
讲到这里,fetch 命令就讲完了,剩下的工作(merge, push)以后再说。
以上是关于git基础教程(27)远程仓库与git fetch的主要内容,如果未能解决你的问题,请参考以下文章