zoukankan      html  css  js  c++  java
  • git命令详解( 七 )

    此为git命令详解的第七篇

    这章我们可以来逐渐揭开 git push、fetch 和 pull 的神秘面纱了。我们会逐个介绍这几个命令,它们在理念上是非常相似的。

        git push的参数

      git fetch 的参数

       git 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

    我们分别来看一下这两条命令的作用……

    如果 push 空 <source> 到远程仓库会如何呢?它会删除远程仓库中的分支!
    例子:

    执行命令: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上。操作够多的吧?!

  • 相关阅读:
    unittest详解 跳过用例的执行(skip)
    python 3 HTMLTestRunner.py文件
    jmeter 如何获取一小时之前的时间戳
    python]用eval强制将字符串转换为字典变量时候出错:NameError: name 'null' is not defined[python]用eval函数 字符串转dict
    Spring Boot 引入自定义yml
    关于爬虫与反爬虫简略方案
    网络回路问题
    MySQL添加新用户、为用户创建数据库、为新用户分配权限
    Spring Boot 项目几种启动方式
    Spring Cloud 之 基础学习资料
  • 原文地址:https://www.cnblogs.com/suihang/p/10556519.html
Copyright © 2011-2022 走看看