当前位置:  开发笔记 > 编程语言 > 正文

Git推错误'[远程拒绝]主 - >主(分支当前已检出)'

如何解决《Git推错误'[远程拒绝]主->主(分支当前已检出)'》经验,为你挑选了16个好方法。

昨天,我发布了一个关于如何将Git存储库从我的一台机器克隆到另一台机器的问题,如何从另一台机器"克隆"?.

我现在能够成功地将Git存储库从我的源(192.168.1.2)克隆到我的目标(192.168.1.1).

但是,当我对文件,a git commit -a -m "test"和a 进行编辑时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).这是一个可能的原因吗?



1> 小智..:

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

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

git config --bool core.bare true

然后删除该文件.git夹中的所有文件.然后,您将能够执行git push远程存储库而不会出现任何错误.


虽然它获得了很多选票,但我认为这不是对这个具体问题的充分答案.指导用户如何干净地创建一个裸仓库将是一半坏,但如果文件需要保持签出,例如当它是用户在两台计算机上使用的存储库时呢?
这是最好的答案,没有其他人在Interwebs洞中提供它.我想我们都搜索了相同的错误信息,我们都非常高兴看到这个.
将源代码库更改为裸机是过度的.您需要做的就是推送到源仓库中的新分支,正如@Robert指出的那样:http://stackoverflow.com/a/2933656/402949.
我不确定你是否打算删除服务器或客户端上的文件...所以我没有删除任何内容,只是在执行`git config --bool core.bare true`后问题就消失了.是否有任何特殊原因需要删除某些文件?如果是这样,您能更准确地了解需要删除的内容吗?
谢谢.我也需要这个.我正在关注[Git社区书籍](http://book.git-scm.com/5_submodules.html)中的子模块教程并点击此障碍.
删除该远程文件夹中的所有文件?你的意思是删除整个网站?我不这么认为......
Aaah,我认为`git init`撤消它并恢复工作树.
@钛不是他的意思。裸仓库仅包含.git文件夹的内容,非裸仓库包含.git文件夹本身,以及检出到工作副本中的文件。实际上,实际上并没有太多理由希望您的远程回购有工作副本,因此您可以简单地删除工作副本文件,但是保留`.git`,以便您的远程成为裸回购。
So how will the site run without any files? O__O

2> Robert Gould..:

我开始学习Git时,我遇到了同样的错误.其他一些答案显然不适合Git的新手!

(我将使用非技术术语来理解这个想法.)无论如何,发生的事情是你有两个存储库,一个是你最初创建的原始版本,另一个是你刚刚创建的工作版.

现在,您在工作存储库中并使用"主"分支.但是,您也恰好在原始存储库中"登录"到同一个"主"分支.既然你已经在原版中"登录"了,Git担心你可能会陷入困境,因为你可能正在研究原版并搞砸了.因此,您需要返回原始存储库并执行"git checkout someotherbranch",现在您可以毫无问题地推送.

我希望这有帮助.


只是为了更清楚,在回购中,这是推动的目标:`git checkout -b tmp`.然后在源代码中:`git push`.然后回到目标(可选):`git checkout master; git branch -d tmp`
+1更有帮助,谢谢罗伯特.在我的情况下,我没有意义转换为裸仓库.只需要"停用"您尝试推送的分支.说得通.
@ FMaz008:只需创建一个虚拟分支(git checkout -b dummy)
Hari的评论是最简单的食谱.我只想说,虽然git在很多方面可能都很棒,但是来自svn或者其他任何一个rv,这一切都非常不直观.
男人这比大多数投票的答案要好得多:)谢谢.虽然其他答案也很好点:)
git checkout与svn checkout完全不同.git checkout只是一个"切换当前"选择器.感谢罗伯特提供的丰富答案!
我发现使用两个自己的存储库时不得不结帐另一个分支是愚蠢的。应该有一个选项允许推送已签出的分支。
好答案。来自git的错误消息(通常)。

3> CB Bailey..:

错误消息描述了发生的情况.如果检出该分支,更多现代版本的Git拒绝通过推送更新分支.

在两个非裸存储库之间工作的最简单方法是

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

    通过推送到单独的分支(导入分支),然后将该分支合并到远程计算机上的主分支中.

这种限制的原因是推送操作仅在远程Git存储库上运行,它无法访问索引和工作树.因此,如果允许,对已签出分支的推送将更改为 HEAD 与远程存储库上的索引和工作树不一致.

这将使得很容易意外地提交撤消所有推送的更改的更改,并且很难区分尚未提交的任何本地更改以及新的HEAD,索引和工作树之间的差异.由推动移动引起的HEAD.


好吧,我在答案中描述了可能性.您可以转到192框并从191框中取出(您可能希望将191框添加为命名远程 - 请查看`git remote add box191 <191url>`),或者您可以从191框中推送到一个交替命名的分支(例如`git push origin master:refs/heads/upload`),然后到192框并合并(例如`git merge upload`).
你实际上现在有一种安全的方法可以使用Git 2.0.0(2015年2月)和`git config receive.denyCurrentBranch = updateInstead`推送到非裸机:http://stackoverflow.com/a/28262104/6309:你不再需要选项2.

4> Nowhere man..:

摘要

您无法推送到存储库的一个已检出分支,因为它会以最可能以数据和历史记录丢失而结束的方式弄乱该存储库的用户.但是您可以推送到同一存储库的任何其他分支.

由于裸存储库从未检出任何分支,因此您始终可以推送到裸存储库的任何分支.

根据您的需求,有多种解决方案.

解决方案1:使用裸露的Repostiory

如建议的那样,如果在一台计算机上,您不需要工作目录,则可以移至裸存储库.为避免弄乱存储库,您只需克隆它:

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

现在,您可以将所有想要的地址推送到与以前相同的地址.

解决方案2:推送到未签出的分支

但是如果您需要检查遥控器上的代码,那么您可以使用特殊分支进行推送.假设您在本地存储库中调用了远程origin控制器并且您在分支主控器上.然后你可以做到

machine2$ git push origin master:master+machine2

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

machine1$ git merge master+machine2

尸检的问题

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

所以

A ? B
    ?
[HEAD,branch1]

A ? B ? C
        ?
    [HEAD,branch1]

但是如果有人可以推送到中间的那个分支,那么用户就可以使用git调用的分离头模式:

A ? B ? X
    ?   ?
[HEAD] [branch1]

现在用户不再在branch1中,没有明确要求签出另一个分支.更糟糕的是,用户现在在任何分支之外,任何新的提交都将悬空:

      [HEAD]
        ?
        C
      ?
A ? B ? X
        ?
       [branch1]

假设,如果在这一点上,用户检出另一个分支,那么这个悬空提交就成了Git 垃圾收集器的公平游戏.


"autopsy"的一个技术修正:git实际上不会在推送到的存储库中分离`HEAD`.`HEAD`仍将指向分支,而分支又将指向推送的新提交; 但工作目录和索引/暂存区域将不加修改.无论是谁在推送到存储库,现在都必须努力从推送的效果中恢复:弄清楚是否有任何保存更改,如果这样仔细安排保存它们.
实际上,当我需要推送到非裸存储库时,我发现了许多情况,并且我使用了解决方案2.此外,我推送非裸存储库的分支绝不是临时分支,它的作用与远程跟踪分支类似.

5> 小智..:

您可以通过编辑.git/config目标服务器来解决此"限制" .添加以下内容以允许将git存储库推送到即使它被"签出":

[receive]
denyCurrentBranch = warn

要么

[receive]
denyCurrentBranch = false

第一个将允许推动,同时警告可能会弄乱分支,而第二个将静静地允许它.

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


我使用上面的方法用`cd .. && git reset --hard` post-receive hook进行部署.哈金,但有效.
后者的命令行版本将是`git config receive.denyCurrentBranch warn`
使用它将代码"部署"到服务器将不起作用.即使您禁用警告以便可以推送到已签出的分支,也不会在推送时更新工作副本.
**这应该是公认的答案.**我们中的一些人知道我们在做什么,而不是Git的初学者.这是那些人的答案.
哈,但问题是**不是**那些*那些*人.

6> Ciro Santill..:

git config --local receive.denyCurrentBranch updateInstead

https://github.com/git/git/blob/v2.3.0/Documentation/config.txt#L2155

在服务器存储库中使用它,如果不会发生未跟踪的覆盖,它还会更新工作树.

如VonC在评论中提到的那样,它被添加到Git 2.3 中.

我编译了Git 2.3并尝试了一下.样品用法:

git init server
cd server
touch a
git add .
git commit -m 0
git config --local receive.denyCurrentBranch updateInstead

cd ..
git clone server local
cd local
touch b
git add .
git commit -m 1
git push origin master:master

cd ../server
ls

输出:

a
b

是的,b被推了!



7> stackdump..:

我喜欢在远程盒子上仍然有一个可用的存储库的想法,但我喜欢使用:而不是虚拟分支.

git checkout --detach

这似乎是Git的一个非常新的特性- 我使用的是git版本1.7.7.4.


然后推送您的更改后,您可以使用:`git checkout master`返回主分支.只有这样才能应用您的更改.

8> 小智..:

我遇到过同样的问题.对我来说,我使用Git push将代码移动到我的服务器上.我从不更改服务器端的代码,所以这是安全的.

在存储库中,您正在推送键入:

git config receive.denyCurrentBranch ignore

这将允许您在存储库工作副本时更改存储库.

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

git checkout -f

这将使您推送的更改反映在远程计算机的工作副本中.

请注意,如果您在要推送的工作副本中进行更改,这并不总是安全的.



9> 小智..:

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

在您的远程服务器上:

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

好的,来自您当地的分支机构:

git push origin master:master


谢谢这是我的解决方案,因为我在远程服务器上省略了'--bare'.似乎这个问题的答案取决于您是否使用远程服务器repo作为工作目录,对于后一种情况,这是正确的答案.
我不明白:SI试图创建和克隆一个裸仓库,但克隆没有下载任何东西,推送没有上传,所以这不起作用... :-)我读了关于裸回购的教程,但他们说这是一个简单的回购没有文件...这绝对不是我想要的......

10> Jemenake..:

你可能做了什么导致这个:

当你去敲一个小程序时就会发生这种事情.你即将改变已经有效的东西,所以你施放了你永久无法解决的3级法术:

machine1:~/proj1> git init

然后你开始添加/提交.但是,然后,项目开始变得更加复杂,你想从另一台计算机(如你的家用电脑或笔记本电脑)上工作,所以你做了类似的事情

machine2:~> git clone ssh://machine1/~/proj1

它克隆,一切看起来都很好,所以你从machine2处理你的代码.

然后 ......你试图从机器2推送你的提交,你会在标题中收到警告信息.

这条消息的原因是因为您从中提取的git repo有点仅用于machine1上的该文件夹.你可以很好地克隆它,但推动可能会导致问题.在两个不同位置管理代码的"正确"方式是使用"裸"repo,就像已经建议的那样.裸回购没有设计有什么工作正在进行,它是为了协调来自多个来源的提交.这就是为什么评价最高的答案建议删除除.git文件夹之外的所有文件/文件夹git config --bool core.bare true.

澄清最受欢迎的答案:对该答案的许多评论都说"我没有从机器1中删除非.git文件,我仍然能够从机器2提交".那就对了.但是,那些其他文件现在完全与git repo"脱离"了.去尝试git status那里,你应该看到像"致命:这个操作必须在工作树中运行"之类的东西.因此,删除文件的建议不是因为machine2的提交将起作用 ; 这样你就不会感到困惑,并认为git仍在跟踪这些文件.但是,如果您仍想处理machine1上的文件,删除文件是一个问题,不是吗?

那么,你应该怎么做?

取决于你计划在机器1和机器2上工作多少...

如果您已完成从machine1开发并将所有开发都移至machine2 ...只需执行评价最高的答案建议:git config --bool core.bare true然后,可选地,从该文件夹中删除.git以外的所有文件/文件夹,因为它们没有跟踪,可能会造成混乱.

如果您在machine2上的工作只是一次性的事情,而且您不需要继续开发那么...那么就不要费心去做一个简单的回购; 只需ftp/rsync/scp/etc. 您的文件来自机器*2*在机器上的文件*1*,从机器*1*提交/推送,然后从机器*2*删除文件.其他人建议创建一个分支,但我认为如果你只是想在一次性的基础上合并一些开发来自另一台机器,那就太麻烦了.

如果您需要继续在machine1和machine2上进行开发......那么您需要正确设置.您需要将您的仓库转换为裸仓,然后您需要在machine1上复制它以供您工作.可能最快的方法是做

machine1:~/proj1> git config --bool core.bare true
machine1:~/proj1> mv .git/ ../proj1.git
machine1:~/proj1> cd ..
machine1:~> rm -rf proj1
machine1:~> git clone proj1.git
machine1:~> cd proj1

非常重要:因为你已经将repo的位置从proj1移动到proj1.git,你需要在machine2上的.git/config文件中更新它.之后,您可以从machine2提交更改.最后,我尝试将我的裸存储库放在一个中心位置,远离我的工作树(即不要将'proj1.git'放在与'proj1'相同的父文件夹中).我建议你这样做,但我想让上面的步骤尽可能简单.



11> Jack Senecha..:

通过一些设置步骤,您可以使用单线程轻松地将更改部署到您的网站

git push production

这很简单,你不需要登录远程服务器并做任何事情.请注意,如果您不将生产结帐用作工作分支,这将最有效!(OP的工作范围略有不同,我认为@Robert Gould的解决方案很好地解决了这个问题.这个解决方案更适合部署到远程服务器.)

首先,您需要在Webroot之外的服务器上的某个位置设置裸存储库.

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/.在那里查看有关正在发生的事情的更详细说明.



12> RibaldEddie..:

你应该只是推到一个裸存储库.裸存储库是没有签出分支的存储库.如果你要cd到一个裸存储库目录,你只能看到.git目录的内容.


事实并非他没有使用"错误"的裸存储库; 事实上,他正在推动检查分支机构.没有证据表明他拥有或想要一个单独的裸存储库,所以你只能推送到非裸存储库的一揽子声明并没有向提问者提供所有选项; 其中一个可能更容易解决他的直接问题.
推送到非裸存储库中的非签出分支没有任何问题.这是一种非常有效的工作方式.

13> kenorb..:

你有3个选择

    再拉一次:

    git pull; git push
    

    推入不同的分支:

    git push origin master:foo
    

    并将其合并到远程(通过git或拉取请求)

    git merge foo
    

    强制它(除非你故意改变提交,否则不推荐rebase):

    git push origin master -f
    

    如果仍然拒绝,请denyCurrentBranch 远程存储库禁用:

    git config receive.denyCurrentBranch ignore
    



14> 小智..:

实际上,将远程设置为非签出分支就足够了.在另一个分支中检出您的遥控器后,您可以推送.



15> hobs..:

我在使用Git同步我的Android手机和笔记本电脑上的存储库时遇到了同样的问题.正如@CharlesBailey建议的那样,我的解决方案是做一次拉动而不是推动.

git push origin master 因为推送到存储库+工作副本的非正常结账,在Android存储库上失败了,因为@ hap497获得了相同的错误消息.

git pull droid master在笔记本电脑存储库和工作副本为我工作.当然,你需要先运行类似的东西git remote add droid /media/KINGSTON4GB/notes_repo/.



16> aircraft..:

检查您.git/config的目标项目:

$ cat .git/config 
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[receive]
    denyCurrentBranch = updateInstead

如果core. barefalse为false,则可以将其设置为true:

$ git config core.bare true

然后在本地推送到远程:

git push remote_repo   // suppose the destination repo is remote_repo

它将成功,在remote_repo中,您可以检查git版本。

$ git log -1
commit 0623b1b900ef7331b9184722a5381bbdd2d935ba
Author: aircraft < aircraft_xxx@126.com>
Date:   Thu May 17 21:54:37 2018 +0800

现在您不能在“工作区”中使用git了:

$ git status
fatal: This operation must be run in a work tree

您应该将其设置bare.bare为false。

$ git config core.bare false

推荐阅读
mobiledu2402852413
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有