此为git命令详解的第七篇
这章我们可以来逐渐揭开 git push、fetch 和 pull 的神秘面纱了。我们会逐个介绍这几个命令,它们在理念上是非常相似的。
git push:
首先来看 git push
。在远程跟踪课程中,你已经学到了 Git 是通过当前检出分支的属性来确定远程仓库以及要 push 的目的地的。这是未指定参数时的行为,我们可以为 push 指定参数,语法是:
git push <remote> <place>
<place>
参数是什么意思呢?我们稍后会深入其中的细节, 先看看例子, 这个命令是:
git push origin master
把这个命令翻译过来就是:
切到本地仓库中的“master”分支,获取所有的提交,再到远程仓库“origin”中找到“master”分支,将远程仓库中没有的提交记录都添加上去,搞定之后告诉我。
我们通过“place”参数来告诉 Git 提交记录来自于 master, 要推送到远程仓库中的 master。它实际就是要同步的两个仓库的位置。
需要注意的是,因为我们通过指定参数告诉了 Git 所有它需要的信息, 所以它就忽略了我们所检出的分支的属性!
我们来看看指定参数的例子,注意下我们当前检出的位置
执行命令:git checkout C0
git push origin master
好了! 通过指定参数, 远程仓库中的 master
分支得到了更新。
如果不指定参数会发生什么呢?
执行命令:git checkout C0
git push
命令失败了(正如你看到的,什么也没有发生)! 因为我们所检出的 HEAD 没有跟踪任何分支
<place>
参数详解
还记得之前课程说的吧,当为 git push 指定 place 参数为 master
时,我们同时指定了提交记录的来源和去向。
你可能想问 —— 如果来源和去向分支的名称不同呢?比如你想把本地的 foo
分支推送到远程仓库中的 bar
分支。
哎,很遗憾 Git 做不到…… 开个玩笑,别当真!当然是可以的啦 :) Git 拥有超强的灵活性(有点过于灵活了)
接下来咱们看看是怎么做的……
要同时为源和目的地指定 <place>
的话,只需要用冒号 :
将二者连起来就可以了:
git push origin <source>:<destination>
这个参数实际的值是个 refspec,“refspec” 是一个自造的词,意思是 Git 能识别的位置(比如分支 foo
或者 HEAD~1
)
一旦你指定了独立的来源和目的地,就可以组织出言简意赅的远程操作命令了,让我们看看演示!
记住,source
可以是任何 Git 能识别的位置:
执行命令:git push origin foo^:master
这是个另人困惑的命令,但是它确实是可以运行的 —— Git 将 foo^
解析为一个位置,上传所有未被包含到远程仓库里 master
分支中的提交记录。
如果你要推送到的目的分支不存在会怎么样呢?没问题!Git 会在远程仓库中根据你提供的名称帮你创建这个分支!
执行命令:git push origin master:newBranch
Git fetch 的参数
我们刚学习了 git push 的参数,很酷的 <place>
参数,还有用冒号分隔的 refspecs(<source>:<destination>
)。 这些参数可以用于 git fetch
吗?
你猜中了!git fetch
的参数和 git push
极其相似。他们的概念是相同的,只是方向相反罢了(因为现在你是下载,而非上传)
让我们逐个讨论下这些概念……
<place>
参数
如果你像如下命令这样为 git fetch 设置 <place> 的话:
git fetch origin foo
Git 会到远程仓库的 foo
分支上,然后获取所有本地不存在的提交,放到本地的 o/foo
上。
来看个例子(还是前面的例子,只是命令不同了)
执行命令:git fetch origin foo
你可能会好奇 —— 为何 Git 会将新提交放到 o/foo
而不是放到我本地的 foo 分支呢?之前不是说这样的 <place> 参数就是同时应用于本地和远程的位置吗?
好吧, 本例中 Git 做了一些特殊处理,因为你可能在 foo 分支上的工作还未完成,你也不想弄乱它。还记得在 git fetch
课程里我们讲到的吗 —— 它不会更新你的本地的非远程分支, 只是下载提交记录(这样, 你就可以对远程分支进行检查或者合并了)。
“如果我们指定 <source>:<destination>
会发生什么呢?”
如果你觉得直接更新本地分支很爽,那你就用冒号分隔的 refspec 吧。不过,你不能在当前检出的分支上干这个事,但是其它分支是可以的。
这里有一点是需要注意的 —— source
现在指的是远程仓库中的位置,而 <destination>
才是要放置提交的本地仓库的位置。它与 git push 刚好相反,这是可以讲的通的,因为我们在往相反的方向传送数据。
理论上虽然行的通,但开发人员很少这么做。我在这里介绍它主要是为了从概念上说明 fetch
和 push
的相似性,只是方向相反罢了。
来看个疯狂的例子:
执行命令:git fetch origin foo:bar
哇! 看见了吧, Git 将 foo~1
解析成一个 origin 仓库的位置,然后将那些提交记录下载到了本地的 bar
分支(一个本地分支)上。注意由于我们指定了目标分支,foo
和 o/foo
都没有被更新。
如果执行命令前目标分支不存在会怎样呢?我们看一下上个对话框中没有 bar 分支的情况。
执行命令:git fetch origin foo:bar
看见了吧,跟 git push 一样,Git 会在 fetch 前自己创建立本地分支, 就像是 Git 在 push 时,如果远程仓库中不存在目标分支,会自己在建立一样。
没有参数呢?
如果 git fetch
没有参数,它会下载所有的提交记录到各个远程分支……
执行:git fetch
古怪的 <source>
Git 有两种关于 <source>
的用法是比较诡异的,即你可以在 git push 或 git fetch 时不指定任何 source
,方法就是仅保留冒号和 destination 部分,source 部分留空。
git push origin :side
git fetch origin :bugFix
我们分别来看一下这两条命令的作用……
执行命令:git push origin :foo
就是这样子, 我们通过给 push 传空值 source,成功删除了远程仓库中的 foo
分支, 这真有意思...(所以我们以后要慎用这个,万一搞丢了分支还得麻烦)
如果 fetch 空 <source> 到本地,会在本地创建一个新分支。
执行命令:git fetch origin :bar
很神奇吧!但无论怎么说, 这就是 Git!
Git pull 参数
既然你已经掌握关于 git fetch
和 git push
参数的方方面面了,关于 git pull 几乎没有什么可以说的了
因为 git pull 到头来就是 fetch 后跟 merge 的缩写。你可以理解为用同样的参数执行 git fetch,然后再 merge 你所抓取到的提交记录。
还可以和其它更复杂的参数一起使用, 来看一些例子:
以下命令在 Git 中是等效的:
git pull origin foo
相当于:
git fetch origin foo; git merge o/foo
还有...
git pull origin bar~1:bugFix
相当于:
git fetch origin bar~1:bugFix; git merge bugFix
看到了? git pull 实际上就是 fetch + merge 的缩写, git pull 唯一关注的是提交最终合并到哪里(也就是为 git fetch 所提供的 destination 参数)
一起来看个例子吧:
如果我们指定要抓取的 place,所有的事情都会跟之前一样发生,只是增加了 merge 操作
执行命令:git pull origin master
看到了吧! 通过指定 master
我们更新了 o/master
。然后将 o/master
merge 到我们的检出位置,无论我们当前检出的位置是哪。
pull 也可以用 source:destination 吗? 当然喽, 看看吧:
执行命令:git pull origin master:foo
哇, 这个命令做的事情真多。它先在本地创建了一个叫 foo
的分支,从远程仓库中的 master 分支中下载提交记录,并合并到 foo
,然后再 merge 到我们的当前检出的分支 bar
上。操作够多的吧?!
git命令详解( 七 )的更多相关文章
-
Git 命令详解及常用命令
Git 命令详解及常用命令 Git作为常用的版本控制工具,多了解一些命令,将能省去很多时间,下面这张图是比较好的一张,贴出了看一下: 关于git,首先需要了解几个名词,如下: 1 2 3 4 Work ...
-
Git初探--笔记整理和Git命令详解
几个重要的概念 首先先明确几个概念: WorkPlace : 工作区 Index: 暂存区 Repository: 本地仓库/版本库 Remote: 远程仓库 当在Remote(如Github)上面c ...
-
Git命令详解
一个中文git手册:http://progit.org/book/zh/ 原文:http://blog.csdn.net/sunboy_2050/article/details/7529841 前面两 ...
-
git命令详解( 四 )
此篇为git命令详解的第四篇,话不多说,我们直接上知识点好吧 git Push 偏离的工作 gitPush: 此命令负责将你的变更上传到指定的远程仓库,并在远程仓库上合并你的新提交记录.一旦 git ...
-
git命令详解( 二 )
这是git详解的第二篇,最近这个加班有点虚,所以文章也写的比较懒了,一到加班不得已,保温杯里泡枸杞啊,不扯了,今天我们来看看git的第二篇 这篇内容主要是git的一些远程命令 远程仓库 git clo ...
-
Git命令详解(一)-个人使用
本文暂时不会涉及到团队如何使用Git的内容,而是从个人的角度探讨如何用好Git. 约定 绿色的5位字符表示提交的ID,文中用<commit>表示,分别指向父节点.分支用橘色显示,分别指向特 ...
-
git命令详解( 八)
此为记录git的第八篇,前七篇为远程篇,工作中最常用的都在前七篇,因为要在远程分支上合作开发 在提交树上移动 撤销变更 在提交树上移动 在接触 Git 更高级功能之前,我们有必要先学习在你项目 ...
-
git命令详解( 六 )
此为git命令的第六篇 远程跟踪分支 不知道大家有没有发现在前面几篇中Git 好像知道 master 与 o/master 是相关的.当然这些分支的名字是相似的,可能会让你觉得是依此将远程分支 mas ...
-
git命令详解( 三 )
此篇为git命令的第三篇 目录 git Pull 模拟团队合作 Git Pull 在上一篇的结尾我们已经知道了如何用 git fetch 获取远程的数据, 现在我们学习如何将这些变化更新到我们的工作当 ...
随机推荐
-
js 一些容易错的点
最近在做平台相关功能,需要和js.html.以及使用bootstrap,bootstrap元素大小的设置 是比较难的. js比较容易出错的是,解析json,对象最好是使用json,这样更好解析,arr ...
-
9、java中的final关键字
/* final : 最终.作为一个修饰符, 1,可以修饰类,函数,变量. 2,被final修饰的类不可以被继承.为了避免被继承,被子类复写功能. 3,被final修饰的方法不可以被复写. 4,被fi ...
-
Rails: No such file or directory - getcwd
这个的意思就是你从一个删除的目录里面运行实例:rails s
-
[OJ] Permutation Index
LintCode 197. Permutation Index (Easy) LintCode 198. Permutation Index II (Medium) 感觉这两道题主要考察计算排列组合的 ...
-
Android(java)学习笔记201:网络图片浏览器的实现(ANR)
1.我们在Android下,实现使用http协议进行网络通信,请求网络数据.这里是获取网络上的图片信息,让它可以显示在手机上: 但是我们这个手机连接网络是很费时间,如果我们在主线程(UI线程)中写这个 ...
-
Duff 装置中case情况越多性能越好
猜想:Duff装置再循环里面,直接调用的方法越多(也就是case的数量比较多),性能相对越好 ???!!! 我们基于Duff装置来做进一步的测试. 然后分别添加两个新的函数,一个函数式 case有4种 ...
-
VHDL设计问题
在做算术运算的时候,不可以用std_ulogic_vector,必须是std_logic_vector.
-
vscode同步设置&;扩展插件
首先安装同步插件: Settings Sync 第二部进入你的github如图: 打开设置选项: 新建一个token: 如图: 记住这个token值 转到vscode 按shift+alt +u ...
-
java实现:将一个数逆序输出
前面我们用C语言实现过这个程序,其实java也一样的,很多步骤跟C差不多,但是有些接口和特性可能不同: import java.util.Scanner;//要使用scanner这个类,就需要导入一个 ...
-
Halcon除法
今天,用到了Halcon 的除法.求出两个region的面积,area1,area2.我想求出它们的比值area1/area2.但是发现比值是整数,没有保留小数.应该改为这样area1/real(ar ...