git fetch, FETCH_HEAD 和 origin/master

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15032159/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 15:35:02  来源:igfitidea点击:

git fetch, FETCH_HEAD and origin/master

gitgit-fetch

提问by DanielF

I'm very new to git and I'm having trouble with a simple fetchoperation.

我对 git 很陌生,我在一个简单的fetch操作上遇到了麻烦。

I'm trying to fetch a coworker's progress from his repository. At first I did git fetch HEADwhich prompted git to download about 350MB of data so I was sure it had done something. However, origin/masterended up still pointing to the same old commit (actually it's under the name devbut I'll call it master- he doesn't have a master).

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

After that I tried git fetch origin masterbut it didn't seem to do anything, it only updated FETCH_HEAD. I tagged the FETCH_HEADcommit so I wouldn't lose it, but I'd still like to have an updated remote branch.

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

What was it that went wrong? I do not have access to the remote repository. Can I still fix it at home?

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

回答by David Culp

I'm a bit confused by the commands you use. HEADis usually a label git uses to track the commit that is currently in the working directory. The git fetchcommand expects a remoteor a remote commitconfiguration to know what you want fetched. Using git fetch HEADwould indicate HEADis a remote in your repository. That the command worked without error is curious.

我对您使用的命令有些困惑。 HEAD通常是 git 用来跟踪当前在工作目录中的提交的标签。该git fetch命令需要远程远程提交配置来了解您想要获取的内容。使用git fetch HEAD将指示HEAD您的存储库中的远程。该命令没有错误地工作是奇怪的。

For example: git fetch HEADin the repository I'm currently working results in the following error

例如: 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.

The command git remotewill list all remotes, while git remote --verbosewill include the address of the remote. Could you use this to see if you have a remote defined as HEADand what remote addresses your friends repository?

该命令git remote将列出所有遥控器,同时git remote --verbose将包括遥控器的地址。你能用这个来看看你是否有一个远程定义为HEAD你的朋友存储库的远程地址是什么?

However, my questions aside and to help clear up your confusion. The git fetch ...command only updates remote refs -- not your local ones.

但是,将我的问题放在一边,以帮助消除您的困惑。该git fetch ...命令只更新远程引用——而不是你的本地引用。

To make this clear, look inside the .git folder in your repository (it is hidden by default so you may need to unhide it). You will find a folder structure similar to the following

为清楚起见,请查看存储库中的 .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

Say you checkout the master branch, git checkout master-- git will change your working directory to match the commit data in the 'objects' folder that matches the commit value in the '.git/refs/heads/master' file.

假设您检出 master 分支,git checkout master--git 将更改您的工作目录以匹配“objects”文件夹中与“.git/refs/heads/master”文件中的提交值相匹配的提交数据。

If you then git fetch origin master, the '.git/refs/remotes/origin/master' file is updated to the commit of the master branch on the remote origin -- and all commit data needed for that commit is downloaded and placed in the 'objects' folder.

如果然后git fetch origin master,'.git/refs/remotes/origin/master' 文件将更新为远程源上 master 分支的提交——并且该提交所需的所有提交数据都被下载并放置在“对象”中文件夹。

The important point here is git fetchdoes not update your working directory reflects the local branch checked out and git fetchnever updates a local branch.

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

Using either git merge ...or git rebase ...is needed to update the local masterbranch with the changes in origin/master. git pull ...does both git fetch ...and either git merge ...or git rebase ..., depending on options and configuration (git merge ...is the default).

无论是使用git merge ...git rebase ...需要更新本地master与变化分支origin/mastergit pull ...确实都git fetch ...与任一git merge ...git rebase ...,根据选项和配置(git merge ...为默认值)。

After all that explanation, you want to be able to see what -- if anything -- was fetched from your friends repository. The git branch -avvcommand will list all local and remote branches, with commit numbers and in the case of local branches, what remote branch it is tracking.

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

To see how the branches relate to each other I find it helpful to use a tool to graph the repository tree. There are several to choose from but I find the git logcommand sufficient; such as git log --all --graph --oneline --decorate. Fair warning, this can be quite long and convoluted for a large repository. A shorter output can be obtained with by adding the --simplify-by-decorationargument.

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

To summarize: if you can fix it at home depends on the information in your repository. The above mentioned commands; git remote --verbose, git branch -avvand git log ...should be give you an understanding of the current state of your repository. From there you can determine if you need to do something more to get the data in your local branch(es) using git mergeor git rebase.

总结一下:您是否可以在家中修复它取决于您的存储库中的信息。上面提到的命令;git remote --verbosegit branch -avv并且git log ...应该让您了解存储库的当前状态。从那里您可以确定是否需要做更多的事情来使用git merge或获取本地分支中的数据git rebase

As always, if you run into trouble, post back with what you learn.

与往常一样,如果您遇到麻烦,请将您学到的东西发回。

回答by VonC

Since git 1.8.4 (August 2013), git fetchwill update the remote tracking branch! Not just FETCH_HEAD.

从 git 1.8.4(2013 年 8 月)开始,git fetch将更新远程跟踪分支!不只是FETCH_HEAD

See commit f269048from Jeff King (peff):

提交f269048杰夫·金(peff

When we run a regular "git fetch" without arguments, we update the tracking refs according to the configured refspec.
However, when we run "git fetch origin master" (or "git pull origin master"), we do not look at the configured refspecs at all, and just update FETCH_HEAD.

We miss an opportunity to update "refs/remotes/origin/master" (or whatever the user has configured). Some users find this confusing, because they would want to do further comparisons against the old state of the remote master, like:

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

我们错过了更新“ refs/remotes/origin/master”(或用户配置的任何内容)的机会。一些用户发现这令人困惑,因为他们想对远程主服务器的旧状态做进一步的比较,例如:

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


But that supposes you have set your repo to fetch branches:

但这假设您已将 repo 设置为获取分支:

git config remote.origin.fetch

If empty:

如果为空:

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

回答by madhead

git fetchdoes not actually touch your working dir. It only fetches the latest changes from remotes. To actually update your current state use git mergeor git rebase. Also, you may use git pullwhich works like shortcut to git fetch+ git merge.

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

The main difference between merge and rebase is that in some cases merge will create a new commit, with accumulated state (non fast-forward merge). IMHO this is bad, as reminds me of the times I used SVN. Rebase just replays your changes on the top of specified commit, so your history is always linear. Just be sure to use the same flow as your colleagues.

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

I suggest you read some stuff about git in general and git flow: a must-read bookand a good article.

我建议你阅读一些关于 git 一般和git flow 的东西:一本必读的书一篇好文章

回答by wadesworld

What you want to do is:

你想要做的是:

  • Add a remote for your coworker
  • Fetch the changes from his repository
  • Create a local branch which refers to his remote branch
  • 为您的同事添加遥控器
  • 从他的存储库中获取更改
  • 创建一个本地分支,引用他的远程分支

Presumably, you've already done step #1. But for completeness, it's:

据推测,您已经完成了第 1 步。但为了完整性,它是:

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

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

where the URL can be any URL format which git supports.

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

Now that you have the remote added, you want to fetch his changes:

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

git fetch coworker

git fetch coworker

This gives you remote branches for each of his branches. Let's say his branch is called "hamster." Now, in order to do work, you create your own local copy of the remote branch

这为他的每个分支提供了远程分支。假设他的分支被称为“仓鼠”。现在,为了工作,您创建自己的远程分支的本地副本

git checkout -b hamster coworker/hamster

git checkout -b hamster coworker/hamster

This creates and switches you to a branch called hamster.

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

From that point on, you can do work on hamster and push it to him with

从那时起,您可以对仓鼠进行操作并将其推给他

git push coworker hamster

git push coworker hamster

the first time, and then just git pushafter that.

第一次,然后就git push在那之后。

Anytime you want to pull down and merge his changes, you can do:

任何时候你想下拉并合并他的更改,你可以这样做:

git pull

git pull