git - Git push错误'[remote rejected] master -> master (branch is currently checked out)'

  显示原文与译文双语对照的内容

昨天,我发表了一个关于如何从我的机器中克隆 Git 库的问题, 如何从另一台机器上'git clone'? 。

现在我可以从我的源( 192.168.1.2 ) 成功克隆一个Git仓库到目标( 192.168.1.1 ) 。

但是当我对一个文件进行编辑时, git commit -a -m"test"git push,我在目标( 192.168.1.1 ) 上得到了这个错误:


git push 
hap@192.168.1.2's password: 
Counting objects: 21, done.
Compressing objects: 100% (11/11), done.
Writing objects: 100% (11/11), 1010 bytes, done.
Total 11 (delta 9), reused 0 (delta 0)
error: refusing to update checked out branch: refs/heads/master
error: By default, updating the current branch in a non-bare repository
error: is denied, because it will make the index and work tree inconsistent
error: with what you pushed, and will require 'git reset --hard' to match
error: the work tree to HEAD.
error: 
error: You can set 'receive.denyCurrentBranch' configuration variable to
error: 'ignore' or 'warn' in the remote repository to allow pushing into
error: its current branch; however, this is not recommended unless you
error: arranged to update its work tree to match what you pushed in some
error: other way.
error: 
error: To squelch this message and still keep the default behaviour, set
error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
To git+ssh://hap@192.168.1.2/media/LINUXDATA/working
! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'git+ssh://hap@192.168.1.2/media/LINUXDATA/working'

我使用了两个不同版本的Git ( 1.7上的远程和本地机器上的1.5 ) 。 这是一个可能的原因?

时间:

你可以简单地将远程存储库转换为裸存储库( 裸存储库中没有工作副本- 该文件夹只包含实际的档案库数据) 。

在远程存储库文件夹中执行以下命令:


git config --bool core.bare true

然后删除该文件夹中除 .git 以外的所有文件。 然后你就可以在远程存储库中执行 git push 而没有任何错误。

当我开始学习的时候,我遇到了同样的错误。 有些其他的答案显然不是为新的Git !

( 我将使用非技术术语来获得这个想法。) 无论如何,发生的事情是,你有两个存储库,一个是原始的,另一个是你刚做的。

现在你在工作库中,正在使用"母版"分支。 但是你在原来的仓库里也正好是"登录中"的"母版"分支。 既然你是"登录中"中的,那么Git担心你可能会混淆,因为你可能正在处理原始的和错误的东西。 所以你需要回到原来的仓库,做一个"git checkout someotherbranch",现在你就可以没有问题了。

我希望这可以帮到你。

错误消息描述了发生了什么。 更现代版本的Git拒绝通过推送更新分支,如果该分支被签出。

在两个non-bare仓库之间工作最简单的方法是

  1. 总是通过拉( 或者获取并合并) 来更新存储库,如果必须

  2. 通过推送到一个独立的分支( 导入分支),然后将该分支合并到远程机器上的主分支。

这里限制的原因是推送操作只能在远程Git存储库上运行,它没有访问索引和工作树的权限。 所以,如果条件允许,一个压在checked-out分支上做将把HEAD要造成与索引和工作树对远程存储库。

这将支持非常轻松地意外地提交一个更改,可以撤销所有的推送更改和信息却很难区分任何本地更改,但还没有提交新 HEAD 与区别的,索引和工作树,它一直在推动 HEAD 所引起。

摘要

你不能推到存储库签出分支之一,因为它会干扰用户的存储库的方式将最有可能结束丢失数据和历史。 但是你可以推到同一个仓库的任何其它分支。

由于裸仓库从来没有签出任何分支,你总是可以推到一个裸仓库的任何分支。

有多种解决方案,具体取决于你的需求。

解决方案 1: 使用裸 Repostiory

如前所述,如果在一台机器上不需要工作目录,你可以移动到一个裸仓库。 为了避免混淆知识库,你可以克隆它:


machine1$ cd.. 
machine1$ mv repo repo.old
machine1$ git clone --bare repo.old repo

现在你可以把你想要的全部都推到同一个地址。

解决方案 2: 推送到Non-Checked-Out分支

但是如果你需要签出远程 <remote> 上的代码,那么你可以使用一个特殊的分支来推动。 假设你在本地存储库中调用了远程 origin,并且你在分支主机上。 然后你可以做


machine2$ git push origin master:master+machine2

然后你需要在 origin 远程仓库中合并它:


machine1$ git merge master+machine2

问题的尸检

当分支被签出时,提交将添加一个新的提交,并将当前分支的头作为其父节点,并将分支的头部移动为新的提交。

所以


A ← B
 ↑
[HEAD,branch1]

变为


A ← B ← C
 ↑
 [HEAD,branch1]

在什么上面去调用分离头 mode,中间画的,可是如果有人推到那个分支用户会得到 itself:


A ← B ← X
 ↑ ↑
[HEAD] [branch1]

现在,用户不再在branch1中,没有显式要求签出另一个分支。 更糟糕的是,用户在变成外面任何分支,而任何新的提交只会被悬空 :


 [HEAD]
 ↓
 C
 ↙
A ← B ← X
 ↑
 [branch1]

假设,如果此时,用户签出了另一个分支,那么这个悬空的提交将成为git的公平游戏垃圾收集器

你可以绕过这个"限制"通过编辑 .git/config 在目标服务器上。 将以下内容添加到允许一个git存储库被推倒,即使它是"签出完毕":


[receive]
denyCurrentBranch = warn

或者


[receive]
denyCurrentBranch = false

第一次将允许推送,同时警告的可能性,混乱了分支,而第二个将只是悄然允许它。

这可以用于将代码用于不用于编辑的服务器。 这不是最好的方法,但是快速部署代码的方法。

我喜欢在远程盒子上使用一个可用的存储库,而不是一个虚拟的分支,我喜欢使用:


git checkout --detach

这似乎是 Git的一个新特性- 我正在使用Git版本 1.7.7.4.

你可以重新创建服务器存储库并从本地分支主机推送到服务器主机。

在你的远程服务器上:


mkdir myrepo.git
cd myrepo.git
git init --bare

好,从你的本地分支:


git push origin master:master

我也有同样的问题 对于我,我使用 git push 将代码移动到服务器。 我从不更改服务器端的代码,所以这是安全的。

在仓库中,你将按以下方式输入:


git config receive.denyCurrentBranch ignore

这将允许你在仓库是工作副本时更改它。

运行 git push 后,转到远程计算机并键入:

 
git checkout -f

 

这将使你所做的更改反映在远程机器的工作副本中。

请注意,如果你在正推动的工作副本中进行更改,这并不总是安全的。

通过一些设置步骤,你可以轻松地使用 one-liner

 
git push production

 

这既简单又简单,你不必登录到远程服务器,或者做任何事情。 请注意,如果你不将生产签出用作工作分支,这将是最有效的 ! ( OP工作在一个稍微不同的上下文中,我认为 @Robert的解决方案解决了它。 这里解决方案更适合部署到远程服务器。)

首先,你需要在你的服务器上的某个地方设置一个裸仓库。


mkdir mywebsite.git
cd mywebsite.git
git init --bare

然后创建文件 hooks/post-receive:


#!/bin/sh
GIT_WORK_TREE=/path/to/webroot/of/mywebsite git checkout -f

并使文件可执行文件:


chmod +x hooks/post-receive

在本地机器上,


git remote add production git@myserver.com:mywebsite.git
git push production +master:refs/heads/master

所有设置现在你可以使用 git push production 来部署你的更改 !

这里解决方案的贷记转到 http://sebduggan.com/blog/deploy-your-website-changes-using-git/ 。 在那里寻找更详细的解释。

实际上,将遥控器设置为non-checked分支是足够的。 在不同的分支中签出远程后,可以按。

...