您的“确切步骤”有些问题,因为如果我首先尝试重现问题:
cd path/to/repoA
git init
git add .
git commit
我的系统上有这个:
$ cd /tmp; mkdir btest; cd btest
$ mkdir repoA; cd repoA
$ git init
Initialized empty Git repository in /tmp/btest/repoA/.git/
$ git add .
$ git commit
On branch master
Initial commit
nothing to commit
$
看起来好像你在一个已经存在并且有一些提交的存储库中执行你的git init,否则master 在这一点上仍然是一个未出生的分支。无论如何,现在我稍微改变一下你的步骤:
$ echo 'dummy repo for testing' > README
$ git add .
$ git commit -m initial
[master (root-commit) 82f36fb] initial
1 file changed, 1 insertion(+)
create mode 100644 README
$ git branch -m master liveBranch
$ git branch devBranch
$ git branch
devBranch
* liveBranch
$
现在让我们尝试将其克隆到 /tmp/btest/repoB:
$ git clone /tmp/btest/repoA /tmp/btest/repoB
Cloning into '/tmp/btest/repoB'...
done.
$ cd ../repoB
$ git status
On branch liveBranch
Your branch is up-to-date with 'origin/liveBranch'.
nothing to commit, working directory clean
$
它正在按照你想要的方式工作。
让我们采用不同的方法来重复该问题,首先删除两个测试存储库,然后使用指向 devBranch 的 HEAD 创建一个新存储库,然后克隆该存储库:
$ cd /tmp/btest
$ rm -rf *
$ mkdir repoA; cd repoA; git init
Initialized empty Git repository in /tmp/btest/repoA/.git/
$ echo > README; git add README; git commit -m initial
[master (root-commit) 8278cc4] initial
1 file changed, 1 insertion(+)
create mode 100644 README
$ git branch -m master devBranch
$ cd ..; git clone repoA repoB; (cd repoB; git status; git branch -A)
Cloning into 'repoB'...
done.
On branch devBranch
Your branch is up-to-date with 'origin/devBranch'.
nothing to commit, working directory clean
* devBranch
remotes/origin/HEAD -> origin/devBranch
remotes/origin/devBranch
$
所以我们的 repoB 处于合适的状态。现在我们改变 repoA 使它有 HEAD 指向 liveBranch:
$ (cd repoA; git checkout -b liveBranch; git branch)
Switched to a new branch 'liveBranch'
devBranch
* liveBranch
$
如果我们在 repoB 中向 git 请求 git pull,我们现在应该期望发生什么?好吧,让我们看看会发生什么(注意,这是 Git 2.8.1 版本;1.8.4 之前的行为在某些情况下会有点不同):
$ cd repoB; git pull
From /tmp/btest/repoA
* [new branch] liveBranch -> origin/liveBranch
Already up-to-date.
$ git branch -a
* devBranch
remotes/origin/HEAD -> origin/devBranch
remotes/origin/devBranch
remotes/origin/liveBranch
$
现在让我们尝试一些不同的方法,即在 repoB 中运行 git fetch,以及 git ls-remote:
$ git fetch
$ git branch -a
* devBranch
remotes/origin/HEAD -> origin/devBranch
remotes/origin/devBranch
remotes/origin/liveBranch
$ git ls-remote
From /tmp/btest/repoA
8278cc44d45cad50f34dc2c788cd9df7bf9375ec HEAD
8278cc44d45cad50f34dc2c788cd9df7bf9375ec refs/heads/devBranch
8278cc44d45cad50f34dc2c788cd9df7bf9375ec refs/heads/liveBranch
显然git pull 和git fetch 都没有读取新的远程HEAD 状态,或者如果是,则回退到名称到ID 的转换。让我们用新的提交更新 repoA 并重新获取:
$ (cd ../repoA; git commit -m update --allow-empty)
[liveBranch 2234cf1] update
$ git fetch
remote: Counting objects: 1, done.
remote: Total 1 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (1/1), done.
From /tmp/btest/repoA
8278cc4..2234cf1 liveBranch -> origin/liveBranch
$ git branch -a
* devBranch
remotes/origin/HEAD -> origin/devBranch
remotes/origin/devBranch
remotes/origin/liveBranch
$ git ls-remote
From /tmp/btest/repoA
2234cf14c9f7c63785e8fe31b7e5f37bcaf51823 HEAD
8278cc44d45cad50f34dc2c788cd9df7bf9375ec refs/heads/devBranch
2234cf14c9f7c63785e8fe31b7e5f37bcaf51823 refs/heads/liveBranch
$
所以,是的,Git 在初始克隆后根本无法更新 remotes/origin/HEAD,至少在使用绝对路径时是这样。将 URL 更改为 file:///tmp/btest/repoA 没有区别:
$ git config remote.origin.url file:///tmp/btest/repoA
$ git fetch
$ git branch -a
* devBranch
remotes/origin/HEAD -> origin/devBranch
remotes/origin/devBranch
remotes/origin/liveBranch
快速查看源代码表明,在最初的clone 步骤之后,git 从不费心更新remotes/origin/HEAD。