Fetch from origin in Bare Repository in Git does not create "remote branch"

时间:2016-04-04 18:22:23

标签: git

First of all, I know how I can update my Bare Repository. I want to know why when my current repository is bare and I fetch from a remote repository, git creates remote (tracking) branches‍‍‍ except of when I fetch from origin?

I tried this experiment:

I have three directories in current directory: origin, bare_clone and remote. Now:

$ cd ./origin
$ git init
$ cat  > 1
^Z
$ git add 1
$ git commit -m "add 1 in initial commit"



$ cd ../bare_clone
$ git clone --bare ../origin

$ cd ../remote
$ git init
$ cat  > 1
^Z
$ git add 1
$ git git commit -m "add 1 in initial commit"
$ git branch test

$ cd ../bare_clone/origin.git/
$ git remote add remote_name ../../remote/
____________________________________________
$ git fetch remote_name
warning: no common commits
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From ../../remote
 * [new branch]      master     -> remote_name/master
 * [new branch]      test       -> remote_name/test
____________________________________________
$ git branch -a
* master
  remotes/remote_name/master
  remotes/remote_name/test
____________________________________________
$ cd ../../origin/
$ git branch origin_test_branch
____________________________________________
$ cd ../bare_clone/origin.git/
t$ git fetch origin
From path/to/bare_clone/../origin
 * branch            HEAD       -> FETCH_HEAD
____________________________________________
$ git branch -a
* master
  remotes/remote_name/master
  remotes/remote_name/test

You can see two remote branches are created for tracking branches of remote_name repository but there is no remote branch for tracking branch origin_test_branch of origin.

1 个答案:

答案 0 :(得分:3)

A --bare clone is generally intended as a recipient for push operations (and nothing else), so it's not really expected to do fetches.

If you look at the config file of a --bare clone you will see:

$ cat config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = true
[remote "origin"]
    url = ...

Note the lack of a fetch = line in the [remote "origin"] section. This means that no references are to be copied by default when doing git fetch (since the references copied are those listed in the fetch = lines).

Compare this with, e.g., git clone --mirror:

$ cat config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = true
[remote "origin"]
    url = ...
    fetch = +refs/*:refs/*
    mirror = true

which says to overwrite all refs with those obtained from remote origin on fetch operations. Note that this picks up refs/tags/* and refs/notes/* automatically (since it gets every refs/* reference).

You could want the normal "copy only branches, and rename branches while copying" behavior that you get with a non-bare clone. If so you must add the proper fetch = line after creating the bare repository:

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

However, be aware that git fetch may also bring over some (but not all) tags during such a fetch (I'm not sure if git fetch special-cases bare clones here). Since tags do not undergo renaming, this may not be what you want (but then again it may be, you must think about this and decide for yourself).