“git fetch”究竟做了什么。后续提取会覆盖以前的提取吗?

时间:2015-08-07 16:39:52

标签: git github version-control

在我的主分支上,我为另一个分支做了一个“git fetch”。

如何撤消?

我的问题是严格关于git fetch,以及撤消它需要什么操作,然后验证本地repo分支是否与远程repo分支匹配。我正在寻找的答案将揭示git fetch正在下载到repo中的内容。我的第一个假设是它只下载和更新repo的.git目录中的数据。我真正想知道的是,“git fetch”是否完全覆盖了为分支下载的数据(因此可以完美匹配远程分支),还是将远程更改/增量数据更新到我的本地仓库?

进一步澄清:我会打电话给另一个分支,“devbranch”。问题是;而不是先将git切换到devbranch然后获取devbranch,我将devbranch取入master分支。

如果我只是对master执行“git fetch”会覆盖我在master上执行的devbranch fetch,还是仅仅添加到master分支上的乱码?或者我应该做些什么(git reset --hard HEAD)。

谢谢你的帮助。

= = = = = = = = = = = = =

经过多次评论后编辑:

[ - 1--]最重要的是,我试图准确理解“git fetch”的作用。我最初的问题解释了是什么让我意识到我并没有真正理解它。如果您可以解释回购中的“git fetch”更新,请执行,谢谢。更重要的是,后续提取是否会覆盖之前的提取?

[ - 2--]假设我们都同意“git fetch”实际上确实从远程(不是本地文件,但在.git目录中)添加或更新了一些本地存储库中的内容 - 而且 - 并非 - 指定正确的分支或切换到正确的分支(例如,在我的初始问题中),如果应用“git merge”,它可以(?)导致某些内容被破坏。那么有人如何撤消获取。

在正确的分支上使用指定的正确分支进行第二次“git fetch”吗?例如 * git checkout * git fetch origin

以下git手册页中的文字讨论了如何在命令上指定分支。另请注意,fetch命令有一个“--dry-run”暗示某些内容正在更新。在我看来,了解更新内容以及如何撤消在错误分支上进行的提取非常重要。我错过了什么,谢谢你的帮助。

http://git-scm.com/docs/git-fetch

如果未指定远程,则默认情况下将使用原始远程,除非为当前分支配置了上游分支。

- 干运行     显示将要做的事情,而不做任何更改。

2 个答案:

答案 0 :(得分:3)

  

假设我们都同意“git fetch”实际上确实从远程(不是本地文件,但在.git目录中)添加或更新了一些本地存储库 - 并且 - 没有指定正确的分支或被切换到正确的分支(例如在我最初的问题中),如果应用“git merge”,它可能会导致某些内容被破坏。那么有人如何取消获取。

这混合了抓取和合并。即使您指定了错误的分支,也没有运行git fetch的危险。我建议你不要费心去取特定的分支,只需要git fetch一切。它更简单,更安全,除非你的存储库有很多巨大的分支,否则效率很高。

然而,合并错误的分支是一个问题。它不会“破坏”任何东西,因为存储库没有被破坏,但你最终会得到错误的代码,可能还有很多冲突。幸运的是,a bad merge can be undone

获取和合并作为两个单独的步骤并指定要获取和合并的分支是不必要的,并且导致您所犯的那种错误。只有git pull(fetch + merge)更简单,让Git找出要获取和合并的内容。 Git有一个tracking branch的概念,它是运行git pull时要合并的远程分支。例如,master通常跟踪origin/master。运行git pull时,Git将获取然后与当前分支的跟踪分支合并。这避免错误地与错误的分支合并。

git fetch会做这些事情。

  1. 获取远程存储库或您请求的特定分支的所有引用(分支名称及其指向的提交)。
  2. 下载填写每个参考文献的完整历史记录所需的所有对象(提交和文件/ blob)。它还可以获得任何标签。
  3. 更新您的远程跟踪分支(例如origin/blah)以匹配。
  4. git fetch不会更改任何本地分支机构。这就是为什么运行git fetch通常是无害的,并且几乎不需要撤消它。

    例如,假设你有这个......

    LOCAL
    A - B - C - D - E [origin/master] - H - I [master]
                 \
                  F - G [my-branch]
    
    ORIGIN
                          3 - 4 [origin/other-branch]
                         /
    A - B - C - D - E - 1 - 2 [master]
    

    运行git fetch之后你就拥有了这个。

    LOCAL
                        3 - 4 [origin/other-branch]
                       /
                      1 - 2 [origin/master]
                     /
    A - B - C - D - E - H - I [master]
                 \
                  F - G [my-branch]
    
    ORIGIN
                          3 - 4 [other-branch]
                         /
    A - B - C - D - E - 1 - 2 [master]
    

    您当地的分行保持不变。 Git只添加了新的提交并移动(或添加)了远程分支。您当地的所有分支机构都不受影响。 mastermybranch留在原地。没有合并或快进或变基。这一切都发生在git-pull的一部分。 pull实际上只是fetch加上merge

    git-fetch就是这样......

    • origin master位于提交2。
      • 我没有提交2,请下载。
      • 提交2的父级是提交1.我没有,下载它。
      • 提交1的父母提交E.我知道,我们已经完成了。
      • origin/master移至提交2。
    • 在提交4处有一个名为other-branch的新分支。
      • 我没有提交4,请下载。
      • 提交4的父级是提交3.我没有,下载它。
      • 提交3的父母提交1.我知道,我们已经完成了。
      • 在提交4处创建origin/other-branch

    这称为"the dumb protocol"。大多数Git安装使用称为“智能协议”的更有效的技术,通过完成大部分工作来确定需要在服务器端获取哪些提交并批量交付它们,从而减少了查询的数量。当Git使用没有特殊Git支持的服务器时,它只会使用哑协议,例如普通的HTTP服务器。哑协议对于理解正在发生的事情仍然很有用。

    没有单一命令撤消git-fetch,但您可以使用the technique in this answerorigin/master移回其先前位置,以手动移动参考文献。

    git update-ref refs/remotes/origin/master refs/remotes/origin/master@{1}
    

    Git使用branch@{#}语法维护分支位置的历史记录(分支只是提交上的标签)。 origin/master@{1}origin/master的先前位置。

答案 1 :(得分:3)

Git fetch only 影响本地持有的“远程”分支。

这个概念导致了很多混乱 重要的是要了解存储代码的主要“位置”:

  1. 在本地作为常规文件(您的“工作区”)。
  2. 本地作为.git/(您的'索引')中的分支。
  3. 本地作为远程区域中的分支.git/(您的本地存储库)。
  4. 远程服务器(可能是“裸” - 没有.git目录,文件只放在工作目录通常所在的顶级目录中。
  5. 因此,当您进行提取时,您正在更新3)

    另一方面,当你拉动时,那些分支是:

    从远程检索到本地存储库(3) 放置(或更新)在您当地的分支机构(2) 处理以获取在文件系统中本地创建或更新的提交中的实际文件。

    您可能会发现https://stackoverflow.com/a/9204499/631619很有帮助

    您对git pull的担心更合适,如果您在不同的分支中,您可能会意外地从错误的分支合并代码。我做到了。