Differences between git remote update and fetch?

不羁岁月 提交于 2019-11-27 06:08:58

UPDATE: more information!

I should have done this from the start: I grepped the Git release notes in Git's Git repo (so meta!)

grep --color=always -R -C30 fetch Documentation/RelNotes/* | less

Then I did a less search for --all, and this is what I found under the release notes for Git version 1.6.6:

git fetch learned --all and --multiple options, to run fetch from many repositories, and --prune option to remove remote tracking branches that went stale. These make git remote update and git remote prune less necessary (there is no plan to remove remote update nor remote prune, though).

Version 1.6.6 wasn't released until December 23rd, 2009, and the Original Poster asked his question on December 6th 2009.

So as you can see from the release notes, the authors of Git were aware of the fact that the git remote update command functionality was being duplicated somewhat by git fetch, but they decided not to remove it, maybe for backward compatibility with existing scripts and programs, or maybe because it's just too much work and there are higher priority items.


Original answer with more details

xenoterracide's answer is 3.5 years old now, and Git has gone through several versions since then (it has gone from v1.6.5.5 to v1.8.3.2 as of this writing), and looking at the current documentation for git remote update and git fetch, it looks like they both can perform basically the same function of fetching new commits from multiple remotes, given the right options and arguments.

Fetching all remotes

One way to fetch multiple remotes is with the --all flag:

git fetch --all

This will fetch from all of your configured remotes, assuming that you don't have remote.<name>.skipFetchAll set for them:

If true, this remote will be skipped by default when updating using git-fetch(1) or the update subcommand of git-remote(1). — git-config documentation

This would be equivalent to using

git remote update

without specifying any remote group to fetch, and also not having remotes.default set in your repo configuration, and also that none of your remotes have remote.<name>.skipDefaultUpdate set to true.

The current 1.8.3.2 documentation for Git's configuration doesn't mention the remotes.default setting, but I consulted The Almighty Google about it and found this helpful explanation from Mislav Marohnić:

$ git config remotes.default 'origin mislav staging'
$ git remote update

# fetches remotes "origin", "mislav", and "staging"

You can define a default list of remotes to be fetched by the remote update command. These can be remotes from your teammates, trusted community members of an opensource project, or similar.

So presumably, if you have remotes.default set, and not all of your remotes are listed in it, then git remote update won't fetch all remotes that your repo is "aware" of.

As for the remote.<name>.skipDefaultUpdate setting, the Git docs explain it thusly:

If true, this remote will be skipped by default when updating using git-fetch(1) or the update subcommand of git-remote(1).

Fetching a specified group of remotes

Instead of fetching all remotes, both fetch and remote update allow you to specify multiple remotes and groups of remotes to fetch:

git fetch [<options>] <group>
git fetch --multiple [<options>] [(<repository> | <group>)…]

git fetch [<options>] <group> allows you to fetch multiple remotes that are part of a group (to borrow another example from Mislav):

$ git config remotes.mygroup 'remote1 remote2 ...'
$ git fetch mygroup

git fetch --multiple allows you to specify several repositories and repository groups to fetch at once (from the docs):

Allow several <repository> and <group> arguments to be specified. No <refspec>s may be specified.

Ambiguity in git remote update documentation

The synopsis for git remote update specifies that the command syntax is as follows:

git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)…]

Notice the last part, [(<group> | <remote>)…]? The trailing dots ... imply that you can specify multiple groups and remotes with the command, which would mean it behaves in the same way as git fetch --multiple...see how the syntax between the two is so similar?

However, in the same document, the explanation for the update command says nothing about specifying multiple group and remote arguments, only that it

Fetch[es] updates for a named set of remotes in the repository as defined by remotes.<group>.

So it's unclear if git remote update works identically to git fetch --multiple with regard to specifying multiple individual remotes and multiple remote groups.

Fetching a single remote

Finally, everyone knows the simple case of fetching a single remote:

git fetch <remote>

It might be the case that you can also use

git remote update <remote>

to do the same thing, but as I mentioned in the previous section, the documentation for git remote update is unclear about whether it's possible to fetch anything other than a single group of remotes with the command.

Wrapup

As I've explained, git fetch and git remote update behave similarly with regard to fetching from multiple remotes. They share similar syntax and arguments, though git fetch is shorter, so people probably find it easier to type and use.

It may be the case that git remote update can't be used to fetch just a single remote like with git fetch, but as I've pointed out, the documentation doesn't make this clear.

Aside

The duplication in functionality between Git porcelain commands, exemplified by git fetch and git remote update above, is not unique. I've noticed a similar situation with git rebase --onto and git cherry-pick, in that both can take a range of commits to patch onto a new base commit.

I guess that as Git has evolved over the years, some functionality was (inevitably?) duplicated, perhaps sometimes as a convenience for end-users (for example, it's simpler to pass a range to cherry-pick, than to pass a single commit over and over to pick a range). Apparently cherry-pick didn't always accept a range of commits, as explained in the v1.7.2 release notes:

git cherry-pick learned to pick a range of commits (e.g. cherry-pick A..B and cherry-pick --stdin), so did git revert; these do not support the nicer sequencing control rebase [-i] has, though.

xenoterracide

Yes and no. git remote update fetches from all remotes, not just one.

Without looking at the code to see if remote update is just a shell script (possible) it, basically, runs fetch for each remote. git fetch can be much more granular.

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