I have created a sandbox git repository containing a few commits and a couple of tags, one lightweight and one annotated:
> mkdir one; cd one; git init
> touch a.txt; git add a.txt; git commit -m"a.txt"
> touch b.txt; git add b.txt; git commit -m"b.txt"
> git tag light
> touch c.txt; git add c.txt; git commit -m"c.txt"
> git tag -a annot -m"annot"
I now create a second repository and fetch from the first:
> mkdir two; cd two; git init
> git remote add one <...>/one
> git fetch one master
remote: Counting objects: 9, done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 9 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (9/9), done.
From <...>/one
* branch master -> FETCH_HEAD
* [new branch] master -> one/master
Why have neither of the tags been fetched? I expected they would be, based on the documentation for git fetch
:
By default, any tag that points into the histories being fetched is also fetched; the effect is to fetch tags that point at branches that you are interested in.
Updated with new interesting informational bits. I put this into a shell script for easy testing:
mkdir ttwo && cd ttwo && git init && git remote add one file://[path]
(and then I remove ttwo
after running a test).
Hence each test below is run in the new empty ttwo
. I am also using Git 2.10.1 here, but there should be no significant differences with 2.11 (while there are definitely significant differences compared with Git 1.7, which is still shipping with certain Linux distributions...).
First, let's git fetch
with no refspecs:
$ git fetch one
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 8 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (8/8), done.
From file://[path]
* [new branch] master -> one/master
* [new tag] annot -> annot
* [new tag] light -> light
This is with Git version 2.10.1, with both repositories on the same machine, and using either file:///home/...
or /home/...
. Both fetches (rm -rf texp2
in between as needed) picked up both tags.
Now let's run it with the single refspec master
. From here on I'll leave out the remote:
through From:
stuff, just show what branches and/or tags get updated:
$ git fetch one master
[snip]
* branch master -> FETCH_HEAD
* [new branch] master -> one/master
Here's what happens if we use master:master
, which requires adding --update-head-ok
:
$ git fetch one --update-head-ok master:master
* [new branch] master -> master
* [new tag] annot -> annot
* [new branch] master -> one/master
* [new tag] light -> light
Aha, now we get tags!
Here's what happens if we fetch master
but write it to refs/remotes/origin/master
:
$ git fetch one master:refs/remotes/origin/master
* [new branch] master -> origin/master
* [new tag] annot -> annot
* [new branch] master -> one/master
* [new tag] light -> light
There is a pattern emerging: we have to write to some local ref(s)
Let's fetch master
to x
and light
to dark
(I tried foo
to bar
but that doesn't work because foo
does not exist in repo one):
$ git fetch one master:x light:dark
* [new branch] master -> x
* [new tag] light -> dark
* [new tag] annot -> annot
* [new tag] light -> light
* [new branch] master -> one/master
Now let's fetch master
to nothing, which we know fails standalone, but fetch light
to dark
:
$ git fetch one master light:dark
* branch master -> FETCH_HEAD
* [new tag] light -> dark
* [new tag] annot -> annot
* [new tag] light -> light
* [new branch] master -> one/master
And one last test:
$ git fetch one master light
* branch master -> FETCH_HEAD
* tag light -> FETCH_HEAD
* [new branch] master -> one/master
This did not write to our tags, only to FETCH_HEAD
, plus the usual opportunistic remote-tracking branch update.
The bottom line appears to be that, when giving explicit refspecs, we must write at least one local ref. Fetching with no refspecs works, because that uses the default refspecs in the config file plus the default tags. Fetching with some refspec(s) that write to a local ref works. Fetching with some refspec(s) that only write to FETCH_HEAD
fails. This seems like a bug, but it's not clear what the intent of the code in Git is, and Git's tag update code is horribly twisty.
来源:https://stackoverflow.com/questions/41813643/why-is-git-fetch-not-fetching-any-tags