Git推送错误“ [[远程拒绝]主机->主机(分支当前已签出)”)


961

昨天,我发布了一个问题,关于如何将Git存储库从我的一台计算机克隆到另一台计算机如何从另一台计算机“ git clone”?

现在,我可以成功地将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)。那可能是原因吗?


5
任何老手都能将已接受的答案更改为stackoverflow.com/a/9283833/397872并将线程移至存档或其他内容吗?还是更改所有权或其他?
rishta 2012年

9
现在,您实际上已经有了一种安全的方法,可以使用Git 2.3.0(2015年2月)和git config receive.denyCurrentBranch=updateInsteadstackoverflow.com/a/28262104/6309
VonC

这就是@stigi提到的书的新链接:git-scm.com/book/en/v1/Git-on-the-Server
Abdelilah El Aissaoui '16


但是我不明白为什么会这样以及如何运作?它正在工作,是的,仅此而已。
Tilak Maddy19年

Answers:


1149

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

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

git config --bool core.bare true

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


4
谢谢。我也需要这个。我正在关注Git社区手册中的子模块教程,并遇到了这个障碍。
Shiki 2010年

6
我不确定您是要删除服务器上的文件还是客户端上的文件...所以我没有删除任何内容,而这样做后问题就消失了git config --bool core.bare true。是否有某些特定原因需要删除某些文件?如果是这样,您能否更精确地确定需要删除的内容?
布莱恩·范登堡

24
这是最好的答案,没有人在Interwebs漏洞中提供它。我认为我们都在Google上搜索了相同的错误消息,并且我们都非常高兴阅读此内容。
塞巴斯蒂安·格里戈诺利

40
尽管它获得了很多选票,但我认为这并不是对这个特定问题的真正足够的答案。指导用户如何干净地创建裸仓库是一件坏事,但是如果文件需要保持检出状态(例如当用户在两台计算机上使用的存储库时)怎么办?

9
将源仓库更改为裸机是过大的。您所要做的就是在源存储库中推送到新分支,正如@Robert指出的那样:stackoverflow.com/a/2933656/402949
丹·索洛维

707

开始学习Git时,我遇到了同样的错误。其他一些答案显然不适合刚接触Git的人!

(我将使用非技术性术语来传达想法。)无论如何,正在发生的事情是您有两个存储库,一个是您首先创建的原始存储库,另一个是您刚刚创建的工作库。

现在,您在工作库中,并且正在使用“ master”分支。但是您也碰巧在原始存储库中“登录”到了同一“ master”分支。现在,由于您已经“登录”了原件,因此Git担心您可能会搞砸,因为您可能正在处理原件并弄乱了东西。因此,您需要返回到原始存储库并执行“ git checkout someotherbranch”,现在您可以毫无问题地进行推送了。

我希望这有帮助。


76
+1还有更多帮助,谢谢罗伯特。就我而言,转换为裸仓库是没有意义的。只需“停用”您要推送到的分支。说得通。
埃里克·穆瑟

32
@ FMaz008:只需创建一个虚拟分支(git checkout -b虚拟)
Dror Cohen

14
男人,这比大多数投票的答案要好:)谢谢。尽管其他答案也
很有意义

102
为了更清楚一点,在回购中,这是推送的目标:git checkout -b tmp。然后在源代码库中:git push。然后返回目标(可选):git checkout master; git branch -d tmp
哈里·卡拉姆·辛格

18
Hari的评论是最简单的方法。我只需要说,尽管git从SVN或其他任何RVS的角度来看在许多方面都可能很棒,但这整件事实在是不直观的。
无条件

128

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

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

  1. 总是通过拉取(或提取并合并)来更新存储库,或者,如果需要,

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

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

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


1
谢谢。那我该如何解决我的问题呢?在我的192框中,我做了'$ cd(项目目录)$ git init $(添加一些文件)$ git add。' 然后在191框中执行“ git clone”并编辑一些文件,然后尝试“ git push”。
hap497

16
好吧,我在回答中描述了各种可能性。您可以转到192框并从191框获取(您可能希望将191框添加为已命名的远程对象-参见git remote add box191 <191url>),也可以从191框推送到其他命名的分支(例如git push origin master:refs/heads/upload),然后到192框并合并(例如git merge upload)。
CB Bailey 2010年

3
现在,您实际上已经有了一种安全的方法,可以使用Git 2.3.0(2015年2月)和git config receive.denyCurrentBranch=updateInsteadstackoverflow.com/a/28262104/6309推送到非裸仓库,您不再需要选项2。
VonC'2

122

摘要

您不能将其推送到存储库的一个已签出分支,因为它会以最有可能以丢失数据和历史记录结束的方式惹恼该存储库的用户。但是您可以推送到同一存储库的任何其他分支。

由于裸存储库永远不会签出任何分支,因此您始终可以推送到裸存储库的任何分支。

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

解决方案1:使用裸站

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

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

现在,您可以将所有想要的地址推送到以前的地址。

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

但是,如果您需要在remote上签出代码<remote>,则可以使用特殊的分支来推送。假设在您的本地存储库中您已经调用了远程服务器,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的垃圾收集器来说,这种悬而未决的提交将成为公平的游戏。


3
对“验尸”的一项技术更正:git实际上不会HEAD在推送存储库中分离。 HEAD仍将指向分支,分支将依次指向已推送的新提交;但是工作目录和索引/临时区域将保持不变。现在,无论谁在推送到存储库中工作,都必须努力工作以从推送的影响中恢复:弄清楚是否有要保存的更改,如果有,请仔细安排保存。
torek

要向您的答案中添加其他信息,您几乎没有理由希望人们将其推送到非裸仓库,因此使用裸仓库是最佳解决方案。

2
实际上,当我需要推送到一个非裸仓库时,我发现了很多情况,并且我经常使用解决方案2。另外,我推送到非裸仓库的分支绝不是临时分支,它的作用与远程跟踪分支相似。

我在服务器中创建了一个GIT文件夹,该文件夹将托管由多个用户使用SourceTree创建的所有存储库。我master在本地PC中创建了一个存储库。我将其添加remotes到服务器文件夹中,并尝试将我的存储库推入服务器,以便其他用户可以拉/取它进行处理。我收到以下错误:! [remote rejected] master -> master (branch is currently checked out)如何检入?
SearchForKnowledge

1
@SearchForKnowledge,您是否意识到您是在问我正在回答的问题?
无处可见的人

65

您可以通过.git/config在目标服务器上编辑来解决此“限制” 。添加以下内容以允许将git存储库推送到其中,即使它已“签出”:

[receive]
denyCurrentBranch = warn

要么

[receive]
denyCurrentBranch = false

第一个将允许推送,同时警告可能会弄乱分支,而第二个将悄悄地允许它。

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


7
使用此代码将代码“部署”到服务器将无法正常工作。即使禁用了警告以便可以推送到已签出的分支,也绝不会在推送时更新工作副本。
Arrowmaster

10
我正在将以上方法与cd .. && git reset --hard后接收挂钩一起使用。朴实,但有效。
jholster 2011年

9
后者的命令行版本为git config receive.denyCurrentBranch warn
Andre Holzner '10

4
这应该是公认的答案。我们中有些人知道我们在做什么,而不是Git初学者。这就是这些人的答案。
Qix-蒙尼卡(Monica)

2
哈,但是问题并没有那些人问到。

46

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被推!


@VonC谢谢!这是我对工作中最少示例的痴迷:-)
Ciro Santilli冠状病毒审查六四事件法轮功

提交服务器最新的更改是否有任何问题?
akozi

@akozi我不确定您的意思,如果在拉动之前在本地提交,它的行为将与--bare我认为的传统克隆完全相同:--force需要推送,这会使您在远程上“丢失”提交。
Ciro Santilli冠状病毒审查六四事件法轮功

1
@CiroSantilli新疆改造中心六四事件法轮功现在不用担心。我查看了选项的含义。我认为updateInstead是force的代名词。
akozi

updateInstead不再是receive.denyCurrentBranch的有效值
Xalorous

41

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

git checkout --detach

这似乎是Git的一项非常新功能-我正在使用git版本1.7.7.4。


8
然后,在完成更改后,可以使用:git checkout master返回至master分支。只有这样,您的更改才会被应用。
马自达2014年

30

我遇到过同样的问题。对我而言,我使用Git push将代码移至服务器。我从不在服务器端更改代码,所以这很安全。

在存储库中,您要键入:

git config receive.denyCurrentBranch ignore

这将允许您在存储库为工作副本时对其进行更改。

运行Git推送后,转到远程计算机并输入以下命令:

git checkout -f

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

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


感谢日志,我合并您的建议denyCurrentBranch,并把git checkout -f里面hooks的文件夹如@插孔senechal张贴在这里
埃德森T.什拉赫塔

有没有一种方法可以使文件不显示在远程存储库上而无需执行此命令?即通过本地命令?
罗伊

24

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

在远程服务器上:

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

好,从您当地的分支机构:

git push origin master:master

3
谢谢,这是我的解决方案,因为我在远程服务器上省略了“ --bare”。似乎该问题的答案取决于您是否将远程服务器存储库用作工作目录,对于后一种情况,这是正确的答案。
Cas

2
我不明白:SI试图创建和克隆裸仓库,但是克隆没有下载任何内容,也没有推送上传任何东西,所以这是行不通的... :-)我阅读了有关裸仓库的教程,但是他们说裸仓库不包含任何文件...那绝对不是我要寻找的东西...
inf3rno

22

您可能导致此问题的原因:

当您去敲一个小程序时,就会发生这种事情。您将要更改已在起作用的某些内容,因此您将永久永久性的3级咒语转换为:

machine1:~/proj1> git init

然后您开始添加/提交。但是,随后,该项目开始变得更加参与,您想在另一台计算机(例如家用PC或笔记本电脑)上进行处理,因此您需要执行以下操作

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

它会克隆,一切看起来都不错,因此您可以在machine2上处理代码。

然后 ...您尝试从machine2推送您的提交,并且标题中显示警告消息。

出现此消息的原因是因为您从中提取的git repo只能用于machine1上的该文件夹。您可以克隆,从它只是罚款,但推动可能会造成问题。就像已经建议的那样,在两个不同位置管理代码的“适当”方法是使用“裸”存储库。裸回购没有设计有什么工作正在进行,它是为了协调来自多个来源的提交。这就是为什么最受好评的答案建议您删除 .git文件夹之后的所有文件/文件夹git config --bool core.bare true

澄清最受好评的答案:答案的许多评论都说类似“我没有从machine1删除非.git文件,但我仍然能够从machine2提交”。那就对了。但是,这些其他文件现在已经与git repo完全“分开”了。去git status那里尝试,您会看到类似“致命:此操作必须在工作树中运行”的信息。因此,删除文件的建议不是为了使machine2的提交有效;这样您就不会感到困惑,并认为git仍在跟踪那些文件。但是,如果仍要在machine1上处理文件,则删除文件是一个问题,不是吗?

那么,您真正应该怎么做?

取决于您打算继续在machine1和machine2上工作的数量...

如果您已经完成了从machine1的开发并将所有开发都移到了machine2 ...,请按照最受好评的答案进行操作:git config --bool core.bare true然后,从该文件夹中删除.git以外的所有文件/文件夹,因为它们没有追踪,可能会造成混乱。

如果您在machine2上的工作只是一次性的事情,并且您不需要在那里继续开发……那么就不必花时间编写裸仓库了;只是ftp / rsync / scp / etc。从机器* 2 *上的文件中删除您的文件,从机器* 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

非常重要:因为您已将存储库的位置从proj1移至proj1.git,所以需要在machine2的.git / config文件中对其进行更新。之后,您可以从machine2提交更改。最后,我尝试将裸仓库存放在远离工作树的中央位置(即,不要将“ proj1.git”与“ proj1”放在同一父文件夹中)。我建议您也这样做,但我想使以上步骤尽可能简单。


非常详细和有帮助。我的案子是最后一个,您的指示像个魅力。
pojda

我在情况3中,我做了一些稍微不同的事情:mk git-server; mv .git git-server / proj.git,然后git将git-server / proj.git克隆到1和2(或git remote origin ...),并使用机器2的正确ssh://前缀。我将保留一个裸露的主副本,该副本将与GH或其他HTTP服务器上的正常副本相似,并且将继续在两台计算机上使用推/拉。
zakmck

18

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

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/。在此处查找有关发生的情况的更详细说明。


您的建议对我有很大帮助,但我没有使用bare,我遵循了这个hooks建议,并与(您建议的)合并,并且效果很好。
埃德森T. Szlachta 2014年

11

您应该只推送到裸仓库。裸存储库是没有签出分支的存储库。如果要cd到裸仓库目录,则只会看到.git目录的内容。


9
推送到非裸仓库中的非签出分支没有错。这是一种完全有效的工作方式。
CB Bailey 2010年

足够公平,那行得通。但这不是用户正在做的。
RibaldEddie

13
他不是没有使用“错误”的裸存储库,这并不是事实。这是他正在推送到已签出分支的事实。没有证据表明他拥有或想要一个单独的裸存储库,因此您的笼统声明(他只应推向非裸存储库)并没有为质询者提供所有选择;其中之一可能更容易解决他的紧迫问题。
CB Bailey 2010年

10

您有3个选择

  1. 再次拉动:

    git pull; git push
    
  2. 推入不同的分支:

    git push origin master:foo
    

    并将其合并到远程(通过gitpull-request

    git merge foo
    
  3. 强制执行(不建议这样做,除非您通过故意更改了提交rebase):

    git push origin master -f
    

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

    git config receive.denyCurrentBranch ignore
    

选项2为我工作。远程git init本地git push原始主机:分支远程git merge完成
Jacky Chong

7

实际上,将遥控器设置为非签出分支就足够了。在其他分支中签出遥控器后,即可进行推送。


7

检查您.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

5

使用Git同步Android手机和笔记本电脑上的存储库时,我遇到了同样的问题。对我来说,解决方案是执行拉动,而不是像@CharlesBailey建议的那样进行推动。

git push origin master 对我来说,Android存储库上的错误对我来说失败了,因为推送到存储库+工作副本的裸露状态而导致@ hap497出现了相同的错误消息。

git pull droid master在笔记本电脑存储库上,工作副本对我有用。当然,您之前需要运行git remote add droid /media/KINGSTON4GB/notes_repo/


4

较旧版本的Git用于允许推送到非裸存储库的当前签出分支。

事实证明,这是一件令人困惑的事情。因此,他们添加了您看到的警告消息,这也非常令人困惑。

如果第一个存储库仅充当服务器,则按照其他答案的建议将其转换为裸存储库并完成此操作。

但是,如果您需要在两个都在使用的仓库之间有一个共享分支,则可以通过以下设置来实现

Repo1-将充当服务器,也将用于开发

Repo2-仅用于开发

如下设置Repo1

创建一个分支以共享工作。

git branch shared_branch

为了安全起见,您还应该创建一个$(REPO).git / hooks / update,它拒绝对shared_branch以外的任何其他更改,因为您不希望其他人在您的私有分支机构中乱糟糟。

repo1/.git/hooks  (GIT_DIR!)$ cat update
#!/bin/sh
refname="$1"
oldrev="$2"
newrev="$3"

if [ "${refname}" != "refs/heads/shared_branch" ]
then
   echo "You can only push changes to shared_branch, you cannot push to ${refname}"
   exit 1
fi

现在,在repo1中创建一个本地分支,您将在其中进行实际工作。

git checkout -b my_work --track shared_branch
Branch my_work set up to track local branch shared_branch.
Switched to a new branch 'my_work'

(可能需要git config --global push.default upstream为了git push工作)

现在您可以使用创建repo2

git clone path/to/repo1 repo2 
git checkout shared_branch 

此时,您可以同时安装repo1和repo2来处理shared_branch在repo1 中进行推送和拉取的本地分支,而不必担心该错误消息或repo1中的工作目录不同步。无论您使用哪种常规工作流程都应该有效。


3

好的,如果您想要一个普通的远程存储库,请创建一个额外的分支并签出。将其推入一个分支(未签出)并将其与当前从本地推入后处于活动状态的分支合并。

例如,在远程服务器上:

git branch dev
git checkout dev

在本地设置中:

git push 

在远程服务器上:

git merge dev

2

您可以执行以下测试来查看bare服务器内容的工作方式:

想象一下,您有一个工作站和一个托管有实时站点的服务器,并且您想不时更新此站点(这也适用于两个开发人员通过一个裸露的中间人来回发送工作的情况)。

初始化

在本地计算机上创建一个目录并cd进入该目录,然后执行以下命令:

# initialization
git init --bare server/.git
git clone server content
git clone server local
  1. 首先,您创建一个裸server目录(请注意最后的.git)。该目录仅用作存储库文件的容器。
  2. 然后将服务器存储库克隆到新创建的content目录。这是您的现场/生产目录,将由您的服务器软件提供服务。
  3. 前两个目录位于服务器上,第三个目录是工作站上的本地目录。

工作流程

现在这是基本的工作流程:

  1. 输入local目录,创建一些文件并提交。最后将它们推送到服务器:

    # create crazy stuff
    git commit -av
    git push origin master
    
  2. 现在输入content目录并更新服务器的内容:

    git pull
    
  3. 重复1-2。这content可能是另一位也可以推送到服务器的开发人员,并且local您可能也会从中退出。


2

使用它将其推送到远程上游分支为我解决了这个问题:

git push <remote> master:origin/master

遥控器无法访问上游仓库,因此这是将最新更改添加到该遥控器的好方法


1
更一般而言(因为这是命令的最终效果),请使用git push <remote> master:newbranch。想法是将新分支推送到远程,然后可以将其合并。这样可以避免错误消息中提到的任何不一致问题。
克莱

1

我必须git --init在现有的裸仓库中重新运行,这已经在.git裸仓库树内创建了一个目录-我在git status那里键入后意识到。我删除了,一切都很好:)

(所有这些答案都是不错的,但就我而言,这是完全不同的(据我所知),如前所述。)


1

我敢肯定,大多数查看此问题的人都会在前两个重要答案处停下来,但我仍然想提供我的解决方案。

遇到上述错误时,我进行了Eclipse + EGit Web项目设置。帮助我的仅仅是使用GitHub应用程序,它似乎神奇地解决了这个问题。尽管EGit总是会拒绝推送,但GitHub桌面应用只会耸耸肩,推送我的更改。也许它可以更优雅地处理多登录情况。


1

我发现有一篇文章在5分钟之内Git,它可能对其他人有用。

我在Git版本控制下有一个Xcode项目,我想将该项目推到DC中的虚拟分布式以太网(VDE)。VDE运行Centos 5。

我读到的有关Git的文章都没有提到裸仓库。听起来一切都很简单,直到我尝试了我认为应该很容易来自SVN背景的内容。

这里建议使远程存储库裸露可用。对我来说,更好的方法是将Xcode项目克隆到projectname.git,然后将其复制到远程服务器。然后推动神奇地工作。下一步将是在没有提交错误的情况下推送Xcode,但现在我可以从Terminal进行操作。

所以:

cd /tmp (or another other directory on your system)<br/>
git clone --bare /xcode-project-directory projectname.git<br/>
scp -r projectname.git sshusername@remotehost.com:repos/<br/>

在Xcode中提交后,要从Xcode项目中推送更改,请执行以下操作:

cd /xcode-project-directory<br/>
git push sshusername@remotehost.com:repos/projectname.git<br/>

我敢肯定有一种更平滑,更复杂的方法可以完成上述操作,但至少可以奏效。为使一切都清楚,这里做了一些澄清: /xcode-project-directory是您的xcode项目存储的目录。可能是/Users/Your_Name/Documents/Project_Name。projectname实际上是项目的名称,但是您可以随意调用它。Git不在乎,您会的。

要使用scp,您需要在允许SSH访问的远程服务器上拥有一个用户帐户。任何运行自己的服务器的人都会有这个。如果您使用共享主机或类似的主机,则可能不走运。

remotehost.com是您的远程主机的名称。您可以轻松地使用其IP地址。为了进一步清楚起见,我在带有SSH密钥的远程主机上使用Gitosis,因此在推送时不提示输入密码。“ 托管Git存储库,简单(安全)方式”一文介绍了如何进行所有设置。


1

最好的方法是:

mkdir ..../remote
cd ..../remote
git clone --bare .../currentrepo/

这将克隆存储库,但不会在中创建任何工作副本.../remote。如果查看远程目录,将会看到一个名为的目录currentrepo.git,这可能是您想要的。

然后从您本地的Git存储库中:

git remote add remoterepo ..../remote/currentrepo.git

进行更改后,您可以:

git push remoterepo master

1

我刚在Heroku上部署git仓库时遇到了这个问题。

我不知道为什么Heroku在他们的身边有一个非裸仓库,但是作为一种解决方法,我能够重置远程仓库并重新上传。

您不应该将Heroku的存储库副本用作唯一的git存储库进行协作,以防万一,我会明确地说:除非您确定已将存储库的完整副本安全地存储在其他地方,否则请不要这样做。 Heroku。重置将删除存储库内容。

重置:

  1. 如果还没有,请安装Heroku工具带(其中包含命令行客户端)。
  2. 如果尚未安装heroku-repo插件,请安装它。

    heroku plugins:install https://github.com/heroku/heroku-repo.git
    
  3. 进行重置,这将删除存储库并创建一个新的空存储库

    heroku repo:reset
    
  4. 像往常一样推到Heroku遥控器上;它将重新上传所有内容。


您可能需要安装Heroku回购工具才能正常工作。做heroku plugins:install https://github.com/heroku/heroku-repo.git
诺亚

1

创建空(裸)存储库后,您将需要在远程服务器上更改配置文件,例如

root@development:/home/git/repository/my-project# cat config 

在那里你会看到

[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true

您将把它从false变为true,并删除了logallrefupdates = true(不确定其用法!)

[core]
repositoryformatversion = 0
filemode = true
bare = true

您可以测试以下

$ git remote show origin
* remote origin
Fetch URL: my-portal@development:/home/XYZ/repository/XYZ
Push  URL: my-portal@development:/home/XYZ/repository/XYZ
HEAD branch: (unknown)

如果您无法按此HEAD分支:(未知)。因此,如果HEAD分支是未知的,则应将裸露更改为true,并在推送成功后可以重新使用

git remote show origin

你会看到

 HEAD branch: master

0

对我来说,工作解决方案是:

远程:

git checkout -b some_tmp_name

本地:

git push

远程:

git checkout master
git branch -d some_tmp_name

但这不是真正的解决方案,而只是解决方法。


如果您没有中央存储库,那么这是一个有效的解决方案。
里克

0

以防万一有人觉得有用。对我来说,这是一个git服务器权限问题。我从一开始就签出了项目,并推送了一个简单的文件,然后得到“推送被拒绝:推送到原点/主文件被拒绝”


-1

使用Git,两个常规(非裸露)存储库无法直接来回推/拉文件。必须有一个中间的裸仓库。显然,这就像一对有孩子的已婚夫妇,并且这对夫妇离婚了。父母不会互相交谈,但他们会通过孩子进行交流。

因此,您有一个存储库,将此存储库克隆到一个裸存储库,然后将其克隆到第三个存储库。第一个和第三个可以通过第二个存储库(裸仓库)交换信息。我想这是有道理的,因为您不希望有人未经您的同意就可以将内容检入存储库,因为这可能会导致合并冲突等。

所以,这是一个例子:

在PC上,在〜/ workspace中

git init
echo "line 1" > afile.txt
git add .
git commit -m ‘initial import’
git clone --bare . ../remote-repository.git
git remote add origin ../remote-repository.git
git push --set-upstream origin master

在笔记本电脑上,在〜/ workspace中(请勿执行git init等)

git clone //LJZ-DELLPC/remote-repository.git/ .

//然后进行各种提交,并推送它们:

echo "line 2" > afile.txt
git add afile.txt
git commit -m 'added line 2'
git push    

然后回到PC,在〜/ workspace中

git pull

//然后进行各种提交,并推送它们:

git push

在笔记本电脑上git pull

等等。

这是一个完全具体的示例,所有示例都在一台机器上,直接从命令窗口复制,这样我们就知道没有遗漏任何步骤,它确实起作用了,等等:

lylez@LJZ-DELLPC ~
$ cd gitdir
/home/lylez/gitdir

lylez@LJZ-DELLPC ~/gitdir
$ ls

lylez@LJZ-DELLPC ~/gitdir
$ mkdir repo1

lylez@LJZ-DELLPC ~/gitdir
$ cd repo1
/home/lylez/gitdir/repo1

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git init
Initialized empty Git repository in /home/lylez/gitdir/repo1/.git/

lylez@LJZ-DELLPC ~/gitdir/repo1
$ echo "line 1" > afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git add afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git commit -m 'initial import'
[master (root-commit) f407e12] initial import
 1 file changed, 1 insertion(+)
 create mode 100644 afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git clone --bar . ../repo1-bare-clone
Cloning into bare repository '../repo1-bare-clone'...
done.

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git remote add origin ../repo1-bare-clone

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git push --set-upstream origin master
Branch master set up to track remote branch master from origin.
Everything up-to-date

lylez@LJZ-DELLPC ~/gitdir/repo1
$ cd ..

lylez@LJZ-DELLPC ~/gitdir
$ ls
repo1  repo1-bare-clone

lylez@LJZ-DELLPC ~/gitdir
$ mkdir repo1-remote

lylez@LJZ-DELLPC ~/gitdir
$ cd repo1-remote
/home/lylez/gitdir/repo1-remote

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git clone ../repo1-bare-clone .
Cloning into '.'...
done.

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ ls
afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cat afile.txt
line 1

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ echo "line 2" >> afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git add afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git commit -m 'added line 2'
[master 5ad31e0] added line 2
 1 file changed, 1 insertion(+)

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git push
Counting objects: 3, done.
Writing objects: 100% (3/3), 260 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To /home/lylez/gitdir/repo1-remote/../repo1-bare-clone
   f407e12..5ad31e0  master -> master

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cd ../repo1

lylez@LJZ-DELLPC ~/gitdir/repo1
$ ls
afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ cat afile.txt
line 1

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git pull
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From ../repo1-bare-clone
   f407e12..5ad31e0  master     -> origin/master
Updating f407e12..5ad31e0
Fast-forward
 afile.txt | 1 +
 1 file changed, 1 insertion(+)

lylez@LJZ-DELLPC ~/gitdir/repo1
$ cat afile.txt
line 1
line 2

lylez@LJZ-DELLPC ~/gitdir/repo1
$ echo "line 3" >> afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git add afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git commit -m 'added line 3'
[master 3fa569e] added line 3
 1 file changed, 1 insertion(+)

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git push
Counting objects: 3, done.
Writing objects: 100% (3/3), 265 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ../repo1-bare-clone
   5ad31e0..3fa569e  master -> master

lylez@LJZ-DELLPC ~/gitdir/repo1
$ cd ../repo1-remote/

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ ls
afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cat afile.txt
line 1
line 2

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git pull
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /home/lylez/gitdir/repo1-remote/../repo1-bare-clone
   5ad31e0..3fa569e  master     -> origin/master
Updating 5ad31e0..3fa569e
Fast-forward
 afile.txt | 1 +
 1 file changed, 1 insertion(+)

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cat afile.txt
line 1
line 2
line 3

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git --version
git version 2.1.1

lylez@LJZ-DELLPC ~/gitdir/repo1-remote

这是一个有效的例子,并解释了原因。除了您的评论外,这里完全没有错误信息。
莱尔Z

1
“使用Git,两个常规(非裸机)存储库无法直接来回推/拉文件”-除外。
安德鲁C

好吧,发布一个具体的例子而不是攻击。
Lyle Z

或者你可以用谷歌搜索?stackoverflow.com/questions/1764380/...
安德鲁ç

您站点线程中的第一个响应开始于“ ...但是,根据git ready和官方git wiki,您应该只推送到裸仓库。” 下一个响应指出:“如果您只想尝试推送master-> master,那么该命令就是:git push origin”,那根本行不通,并且有如此之多的帖子。最后一个响应以“我建议在您的服务器中有一个裸存储库和一个本地工作(非裸)存储库”开头,这正是我所建议的。
Lyle Z

-3

我的解决方案(使用中)

  1. 检出远程服务器上的“主服务器”
  2. 在“ dev”分支上本地工作
  3. 将更改推送到远程开发人员
  4. 将开发人员合并到远程主机中

答对了

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.