Update with:
$ git fetch origin +refs/heads/*:refs/heads/* --prune
What does this do?
First an aside: When we speak of a branch named "xyz", git actually addresses it as refs/heads/xyz
. But you can type "xyz
" for short because otherwise it would be insane. (Incidentally, tags are refs/tags/xyz
.) Plain xyz
is ambiguous as it could be a branch, a tag, or the first N letters of a commit hash. refs/heads/xyz
on the other hand explicitly represents a branch.
So even though you can type git fetch origin foo:bar
to grab their foo
branch as named bar
in your repository, you can more explicitly type git fetch origin refs/heads/foo:refs/heads/bar
to do the same thing. (Although if foo
was actually a tag and not a branch, the latter will fail because their refs/heads/foo
doesn't exist. Explicitness ftw.)
git fetch origin refs/heads/*:refs/heads/*
means all their branch are belong to us. The command is run as if the *
part is substituted to their branch name for each of their branches. i.e. git fetch origin refs/heads/abc:refs/heads/abc refs/heads/def:refs/heads/def ...
(assuming they have branches named abc
and def
).
The --prune
option means any branches we have in our repository that matches refs/heads/*
but doesn't exist in their repository are deleted.
Finally, the +
prefix is to allow non-fast-forward fetches. Without it, any update to branches that require force-updates are rejected.
Put together, the end result is that branches in your repository ends up looking exactly the same as theirs.
Here's an example output:
- [deleted] (none) -> bar
* [new branch] foo -> foo
4812558a5f..a6aeec6517 abc -> abc
+ a1b2c3d4e5...1a2b3c4d5e def -> def (forced update)
- The example tells us they have branches
foo
, abc
, def
while we have (had) one extra: bar
- Notice the deletion of
bar
by --prune
and force update of def
allowed by the +
prefix.
Here's what happens instead if +
and --prune
were left off:
* [new branch] foo -> foo
4812558a5f..a6aeec6517 abc -> abc
! [rejected] def -> def (non-fast-forward)
One last thing:
Compare the command at the top with the following:
$ git fetch origin +refs/heads/*:refs/remotes/origin/* +refs/tags/*:refs/tags/* [--prune]
This is essentially what happens when we type git fetch origin [--prune]
!