git fetch,FETCH_HEAD和origin / master

时间:2013-02-22 19:51:41

标签: git git-fetch

我对git很新,我在使用简单的fetch操作时遇到了麻烦。

我正试图从他的存储库中获取同事的进度。起初我做了git fetch HEAD,这促使git下载了大约350MB的数据,所以我确信它已经做了一些事情。但是,origin/master最终仍然指向相同的旧提交(实际上它位于dev的名称下,但我将其称为master - 他没有master )。

之后我尝试了git fetch origin master,但它似乎没有做任何事情,只更新了FETCH_HEAD。我标记了FETCH_HEAD提交,所以我不会丢失它,但我仍然希望有一个更新的远程分支。

出了什么问题?我无权访问远程存储库。我还可以在家修理它吗?

4 个答案:

答案 0 :(得分:16)

我对您使用的命令感到有些困惑。 HEAD通常是git用于跟踪当前在工作目录中的提交的标签。 git fetch命令需要远程远程提交配置才能知道您要提取的内容。使用git fetch HEAD表示HEAD是您的存储库中的远程。这个命令没有错误地运行是好奇的。

例如:我在目前正在使用的存储库中的git fetch HEAD会导致以下错误

fatal: 'HEAD' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

命令git remote将列出所有遥控器,而git remote --verbose将包含遥控器的地址。您是否可以使用它来查看您的远程定义为HEAD以及远程地址为您的朋友存储库?

然而,我的问题放在一边,以帮助澄清你的困惑。 git fetch ...命令仅更新远程引用 - 而不是本地引用。

要明确这一点,请查看存储库中的.git文件夹(默认情况下它是隐藏的,因此您可能需要取消隐藏它)。您将找到类似于以下

的文件夹结构
working directory
|=>.git
|  |=>objects           <= contains data for each commit
|  |=>refs
|     |=>heads
|        |-master       <= file containing current commit of local master branch
|     |=>remotes
|        |=>origin
|           |-master    <= file containing current commit of remote origin's master branch
|-FETCH_HEAD            <= file updated by `git fetch`, contains info of what was fetched

假设你签出了主分支,git checkout master - git会改变你的工作目录以匹配&#39;对象中的提交数据。与&#39; .git / refs / heads / master&#39;中的提交值匹配的文件夹文件。

如果你然后git fetch origin master,&#39; .git / refs / remotes / origin / master&#39;文件被更新为远程源上的主分支的提交 - 并且下载该提交所需的所有提交数据并将其放置在&#39;对象中。文件夹中。

这里的重点是git fetch不更新您的工作目录,反映签出的本地分支,git fetch永远不会更新本地分支。

需要git merge ...git rebase ...使用master中的更改来更新本地origin/master分支。 git pull ...同时git fetch ...以及git merge ...git rebase ...同时执行,具体取决于选项和配置(git merge ...是默认设置)。

在完成所有解释之后,您希望能够看到从朋友存储库中获取的内容(如果有的话)。 git branch -avv命令将列出所有本地和远程分支,带有提交编号,如果是本地分支,则列出它正在跟踪的远程分支。

要了解分支如何相互关联,我发现使用工具绘制存储库树图是有帮助的。有几个可供选择,但我发现git log命令已足够;例如git log --all --graph --oneline --decorate。公平的警告,对于大型存储库来说,这可能会很长并且很复杂。通过添加--simplify-by-decoration参数可以获得更短的输出。

总结一下:如果您可以在家中修复它,取决于您的存储库中的信息。上面提到的命令; git remote --verbosegit branch -avvgit log ...应该让您了解存储库的当前状态。从那里,您可以确定是否需要执行更多操作以使用git mergegit rebase在本地分支中获取数据。

与往常一样,如果遇到麻烦,请回复所学内容。

答案 1 :(得分:9)

自git 1。8。4(2013年8月)起,git fetch将更新远程跟踪分支!不只是FETCH_HEAD

请参阅commit f269048中的Jeff King (peff)

  

当我们运行没有参数的常规“git fetch”时,我们会根据配置的refspec更新跟踪引用。
  但是,当我们运行“git fetch origin master”(或“git pull origin master”)时,我们根本不会查看已配置的refspecs,只需更新FETCH_HEAD

     

我们错过了更新“refs/remotes/origin/master”(或用户配置的任何内容)的机会。有些用户觉得这很混乱,因为他们希望进一步比较远程主机的旧状态,如:

$ git pull origin master
$ git log HEAD...origin/master

但是假设你已经设置了你的repo来获取分支:

git config remote.origin.fetch

如果为空:

git config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'

答案 2 :(得分:4)

git fetch实际上并没有触及你的工作目录。它只从遥控器中获取最新的更改。要实际更新当前状态,请使用git mergegit rebase。此外,您可以使用git pull,其作用类似于git fetch + git merge的快捷方式。

merge和rebase之间的主要区别在于,在某些情况下,merge将创建一个新的提交,具有累积状态(非快进合并)。恕我直言,这很糟糕,让我想起了我使用SVN的时代。 Rebase只是在指定提交的顶部重放您的更改,因此您的历史记录始终是线性的。请务必使用与同事相同的流程。

我建议你阅读一些关于git的内容和 git flow must-read booka good article

答案 3 :(得分:1)

您想要做的是:

  • 为同事添加遥控器
  • 从其存储库中获取更改
  • 创建一个引用其远程分支的本地分支

据推测,你已经完成了第一步。但为了完整起见,它是:

git remote add coworker git://path/to/coworkers/repo.git

其中URL可以是git支持的任何URL格式。

现在你已经添加了遥控器,你想要获取他的更改:

git fetch coworker

这为您的每个分支提供了远程分支。让我们说他的分支被称为“仓鼠”。现在,为了完成工作,您可以创建自己的远程分支的本地副本

git checkout -b hamster coworker/hamster

这会创建并切换到名为hamster的分支。

从那时起,你可以在仓鼠上工作并用

推送给他

git push coworker hamster

第一次,然后只是git push

只要您想要下拉并合并他的更改,您就可以执行以下操作:

git pull