Git fetch and pull with no arguments

走远了吗. 提交于 2019-12-03 11:29:38

问题


I have a git branch checked out named foo.

> git status
# On branch foo
nothing to commit (working directory clean)

It was originally checked out using this command:

> git checkout origin/foo -b foo --track

I want to get updates to this branch from the remote repository. I know that either of these commands will suffice:

> git fetch origin foo # ignore the lack of merging
> git pull origin foo

If I omit the arguments to fetch or pull, will git default to fetching (or pulling) the branch that I currently have checked out? That is, are the following pairs of commands equivalent?

> git checkout foo
> git pull

and

> git checkout foo
> git pull origin foo

回答1:


Unfortunately, whether they are equivalent or not in general depends on which branch you are on, your configuration, phase of the moon, etc.

You can figure this out from the git pull man page, as I've described below, but I would generally try to avoid having to work that out by doing: git fetch origin and then git merge origin/foo. (I wrote a somewhat rambling blog post about this.)

However, your question is really about the default behaviour of git pull when you don't specify a remote or a refspec. We can figure this out from the git pull man page, and in particular the DEFAULT BEHAVIOUR section. This is somewhat tough to figure out, so I've put in bold the only parts that really apply to your question given you given that (a) you are on branch foo, (b) you created that branch as you described in the question, and (c) you haven't been changing your configuration.

Often people use git pull without giving any parameter. Traditionally, this has been equivalent to saying git pull origin. However, when configuration branch.<name>.remote is present while on branch <name>, that value is used instead of origin.

In order to determine what URL to use to fetch from, the value of the configuration remote.<origin>.url is consulted and if there is not any such variable, the value on URL: line in $GIT_DIR/remotes/<origin> file is used.

In order to determine what remote branches to fetch (and optionally store in the remote-tracking branches) when the command is run without any refspec parameters on the command line, values of the configuration variable remote.<origin>.fetch are consulted, and if there aren’t any, $GIT_DIR/remotes/<origin> file is consulted and its Pull: lines are used. In addition to the refspec formats described in the OPTIONS section, you can have a globbing refspec that looks like this:

refs/heads/*:refs/remotes/origin/*

A globbing refspec must have a non-empty RHS (i.e. must store what were fetched in remote-tracking branches), and its LHS and RHS must end with /*. The above specifies that all remote branches are tracked using remote-tracking branches in refs/remotes/origin/ hierarchy under the same name.

The rule to determine which remote branch to merge after fetching is a bit involved, in order not to break backward compatibility.

If explicit refspecs were given on the command line of git pull, they are all merged.

When no refspec was given on the command line, then git pull uses the refspec from the configuration or $GIT_DIR/remotes/<origin>. In such cases, the following rules apply:

  1. If branch.<name>.merge configuration for the current branch exists, that is the name of the branch at the remote site that is merged.

  2. If the refspec is a globbing one, nothing is merged.

  3. Otherwise the remote branch of the first refspec is merged.

When you created the branch foo with:

git checkout origin/foo -b foo --track

... it will have set the following config options, which associate your branch foo with refs/heads/foo in the origin repository:

branch.foo.remote=origin
branch.foo.merge=refs/heads/foo

So, if you put that together with the emboldened sentences above, the answer is "Yes, in this situation you describe, when you're on branch foo, the commands git pull and git pull origin foo are equivalent."




回答2:


Even in the conditions Mark describes, when they appear to be the same, there is still a subtle difference -- git pull origin foo will not update the remote tracking branch, whereas git pull will. This is documented in the manpage for git-pull:

A parameter <ref> without a colon is equivalent to <ref>: when pulling/fetching, so it merges <ref> into the current branch without storing the remote branch anywhere locally

So in your case, for the true equivalent to git pull, you'd need to do git pull origin foo:refs/remotes/origin/foo




回答3:


Yes, they are. The tracking information is saved in .git/config.



来源:https://stackoverflow.com/questions/6860893/git-fetch-and-pull-with-no-arguments

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!