从另一个分支获取文件的内容而不检查它

时间:2018-04-06 15:15:24

标签: git git-branch git-merge git-pull

我正在尝试从另一个分支获取文件的内容 我正在做以下事情:

git checkout branchB some_specific_file.cc  

当前分支不受影响。我怀疑原因是即使我已经完成了git pull我还没有在本地检出branchB。 如果我在回购中刚刚完成pull但从未实际检出过其他分支,那么这个命令是否有办法工作?
有什么东西是平等的:

git pull  
git checkout branchB  
git checkout branchA  
git checkout branchB some_specific_file.cc 

没有实际必须切换到分支,所以最后一个命令工作?

3 个答案:

答案 0 :(得分:3)

TL; DR

我认为你想要的是:

$ git fetch
$ git checkout origin/branchB -- some_specific_file.cc

背景

你在这里犯的根本错误是认为分支意味着什么。 :-)或者更确切地说,分支名称具有某种全局意义 - 但它并没有!

git pull命令用作便捷操作:首先运行git fetch,然后运行第二个Git命令。默认的第二个命令通常是git merge,但是(a)你可以改变它,(b)有一些极端情况。这被认为(但实际上并不)方便的原因是git fetch只有获得新提交。它不影响您的任何分支您的,它们不属于origin之类的远程!)。

通常,在从origin之类的某个远程获取新提交后,您将希望(某些)提交合并到(某些)您自己的分支中。为此,您需要第二个Git命令,例如git mergegit rebase。这里有很多小问题,例如:

  • 您如何知道是否合并,变基或完全做其他事情?
  • 如果您想在多个分支机构上运行该怎么办?

git pull便利命令将所有这些放在一边,并向您保证,无论git fetch做了什么,您都100%确定立即git xxx - 您填写在之前的xxx部分中获取 - 是正确的答案!如果它不是 - 实际上经常是经常,根据我的经验 - 那么git pull是错误的命令。

您在上面做了什么

上面这两个命令的序列:

git pull
git checkout branchB

如果你还没有 branchB,那么创建 new (本地)分支名称{ {1}},指向与现有远程跟踪名称 branchB相同的提交。然后:

origin/branchB

让你回到你的(可能是现有的)分支A上,我们稍后会谈到它。最后的命令:

git checkout branchA

然后从名称git checkout branchB -- some_specific_file.cc 标识的提交中提取该特定文件。 (我在这里添加branchB这是一个好主意,如果文件名类似于--选项或分支名称,则反复使用它; git checkout赢了' t,无论哪种方式都安全。)

git pull = git fetch + git merge

some_specific_file.cc步骤让您的Git调用另一个Git,通常是您以名称git fetch存储的网址。他们的Git列出他们的分支名称,以及哪些提交哈希ID与这些分支名称一起使用。然后你的Git确保你有这些提交,一旦你这样做,设置你的 origin名称​​记住那些哈希ID。

origin/*名称就是我所说的远程跟踪名称; Git称他们为远程跟踪分支名称。他们记住,在你自己的Git存储库中,你的Git最后一次与他们的Git交谈。

因此,由于origin/*运行git pull,因此会产生更新远程跟踪名称的副作用。但是有一个问题:git fetch,为方便起见,限制 git pull提取的名称集。

通常git fetch提取所有其分支名称,更新相应远程跟踪名称的所有。但是,当从git fetch运行时,Git会查看您的当前分支所谓的上游设置。通常,git pull的上游为masterorigin/master的上游为branchA,依此类推。这些是你的分支机构的名字。当origin/branchA运行git pull时,它会说:仅更新此远程跟踪名称。

这最终意味着git fetchgit pull上的不会更新您的branchB,而且#&# 39; s(最终)是一个大问题。你需要颠倒命令的顺序:先检查origin/branchB,然后检查然后拉。 (或者,更好,避免 branchB,但请等一下。)

创建(本地)分支

git pull命令会将您切换到您已有的某个现有分支:

git checkout
例如,

会将您切换到您可能已经拥有的git checkout master 。但是,如果您还没有拥有它,master将扫描您的git checkout名称 - 远程跟踪(不完全是分支)名称 - 在拿走origin/*部分之后看看是否有匹配。

如果是这样,您的Git将创建一个新的本地分支名称,其自身的origin/版本为"上游"

origin/始终只在当前分支

上运行

git merge的最后一步通常是运行git pull。如果您运行:

git merge

这意味着Git应该:

  • 查看现有的git checkout branchB git pull ,或者根据需要从branchB;
  • 创建。{li>
  • 获取并更新origin/branchB(仅限);
  • 运行origin/branchB更新您当前的分支 - git merge - 使用其上游branchBorigin/branchB刚更新。

合并步骤将使您的本地分支git fetch得到更新。

一般情况下,您必须branchB 之前git checkout branchB,以确保git pull是(单个)远程跟踪名称<{1}}更新,然后您自己的本地origin/branchB也会更新。

你不需要

但是你不需要任何来完成你的任务。如果您只运行fetch,更新所有您的branchB名称,然后使用git fetch来识别包含origin/*版本的提交你想要的,你很好。因此,我在顶部建议的最后一组命令。

答案 1 :(得分:2)

您可以运行git fetch来同步远程分支,然后直接从origin/branchB

结帐文件
git checkout origin/branchB some_specific_file.cc 

从远程分支获取特定文件的内容 (假设origin是遥控器的名称)

答案 2 :(得分:0)

git checkout target_branch -- file.cpp

这确实对我有帮助,它使我免于签出整个分支,然后重新构建项目。只需签出我需要的文件即可。避免不必要的重建。非常感谢!