我正在尝试将我的主分支重命名为'liveBranch',创建一个新分支('devBranch'),然后在同一台计算机上的另一个文件夹中克隆repo(称之为repo A)(称之为repo B) 。但是当我这样做的时候,如果我在回购B上做git branch -a
,它会显示回购A的HEAD指向'devBranch'而回购时的git branch -a
A声称'liveBranch'被检出
以下是我的确切步骤(注意:repoA是非空目录):
cd path/to/repoA
git init
git add .
git commit
git branch -m master liveBranch
git branch devBranch
git clone path/to/repoA path/to/repoB
cd path/to/repoB
在回购B中运行git branch -a
返回:
* devBranch
remotes/origin/HEAD -> origin/devBranch
remotes/origin/devBranch
remotes/origin/liveBranch
在回购A中运行git branch -a
时返回:
devBranch
* liveBranch
我认为这可能是因为两个分支实际上都指向同一个提交,因此两个repo在技术上都是错误的。所以我在回购A中的一个分支上提交了一个推进分支并在回购B中做了git pull
,但是仍然发生了断开连接(回购B和回购A不同意哪个分支回购A已经检出)。
答案 0 :(得分:2)
你的“确切步骤”有点不对劲,因为如果我开始试图重现这个问题:
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
$
它按照你想要的方式工作。
让我们采用不同的方法来重复这个问题,从删除两个测试存储库开始,然后创建一个新的存储库,HEAD
指向devBranch,然后克隆该存储库:
$ 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
,至少在使用绝对路径时。将网址更改为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
。
答案 1 :(得分:0)
似乎您正在一个已经存在并有一些提交的存储库中执行 git init
,否则 master
此时仍将是一个未出生的分支。
即使 master 未出生,您仍然可以(现在,Git 2.30,2021 年第一季度)重命名它:
这是用户培训的一部分,为他们将来更改 init.defaultBranch
配置变量做好准备。
请参阅 commit 675704c 的 commit cc0f13c、commit cfaff3a、commit 1296cbe、Johannes Schindelin (dscho
)(2020 年 12 月 11 日)。
(由 Junio C Hamano -- gitster
-- 于 commit 772bdcd 合并,2020 年 12 月 18 日)
branch -m
:允许重命名尚未出生的分支签字人:约翰内斯·辛德林
<块引用>在接下来的一次提交中,我们想给用户一些关于初始分支名称以及如何修改它的建议。
为此,如果 git branch -m <name>
(man) 在没有任何提交的情况下在新初始化的存储库中工作会很好。
就这样吧。
测试表明:
test_expect_success 'branch -m with the initial branch' '
git init rename-initial &&
git -C rename-initial branch -m renamed &&
test renamed = $(git -C rename-initial symbolic-ref --short HEAD) &&
git -C rename-initial branch -m renamed again &&
test again = $(git -C rename-initial symbolic-ref --short HEAD)