向Git代码库推送失败

8

我刚开始使用GIT(之前使用的是cvs),想要像cvs/svn一样设置Git。我执行了以下步骤:

cd o:/repository
git init

cd <working directory>
git clone o:/repository

我现在创建了一个名为file.txt的文件,并添加了一些内容。执行 "git status" 命令会列出相应的更改。
然后我执行:
git add file.txt
git commit file.txt

两者都似乎运行良好。

当我执行git push时,出现以下错误:

No refs in common and none specified; doing nothing.
Perhaps you should specify a branch such as 'master'.
fatal: The remote end hung up unexpectedly
error: failed to push some refs to 'o:/repository'

我尝试先进行拉取操作,以及在推送命令中指定源和主变量,但都没有成功。请问有人能告诉我我漏掉了什么吗?我的系统是64位的Windows 7。
附注:我还尝试过...
git push origin master

我得到以下结果:
Counting objects: 3, done.
Writing objects: 100% (3/3), 251 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error:
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error:
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
To O:/repository
 ! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'O:/repository'

请注意,Git 2.3.0(2015年2月)允许更安全地推送到非裸库:请参见我的答案 - VonC
4个回答

15

几周前我们也遇到了这个问题。意味着你在源代码库中检出了一个工作目录,并且无法推送以进行覆盖。

在源代码库中,你需要将其设置为裸仓库。我不知道是否有一条命令可以完成此操作。以下是我在源代码库中所做的。

> mv repository repository.old
> git clone --bare repository.old repository

我看到你的情况下,源是o:/repository。 源不应该是已检出的工作副本,因此您可以初始化一个裸仓库或按照上述方式复制。 要使您描述的场景通过:

cd o:/repository
git init  --bare

cd <working directory>
git clone o:/repository

git push origin master

这应该可以完美地为您工作:

好的阅读材料:http://www.gitready.com/advanced/2009/02/01/push-to-only-bare-repositories.html


谢谢,那个方法可行,不过稍作修改,我必须调用git push origin master。我希望只需键入git push,git就能知道我从哪里签出/克隆。我即将阅读您发送给我的链接,希望它能澄清--bare存储库是什么以及为什么我不能只调用git push。 - Coder
哦,只是一个小的后续问题,Git 中没有像 CVS 那样定义用户以指定谁可以读写存储库吗? - Coder
据我所知,您需要第三方为您完成这个。我们在 Linux 服务器上运行 gitosis 进行内部开发。这里有一篇关于如何在 Windows 服务器 2008 上设置的文章:http://www.shannoncornish.com/blog/2009/04/gitosis-windows-server-2008/。但如果我可以重新选择,我会只使用 gitorious 或 github - 这就是我现在个人开发时所做的。 - Geoff Lanotte
略微后退一步 - 理论上,您可以使用文件系统权限来管理用户访问。这可能不太美观,但可以起作用。 - Geoff Lanotte
@Coder(上面的3条评论):由于git使用分布式模型,所以没有用户。与CVS / SVN不同,在这些系统中,不同的人将更改推送到共享存储库,而在git中,一个人控制“主”/“官方”存储库并从其他开发人员那里获取更改。但是,您可以通过有效地用计算机程序替换该人来模拟CVS / SVN模型,该程序可以处理访问控制-例如,这就是gitosis的作用。 - David Z

5

对于第一次推送,您需要类似以下的内容:

git push origin master

另外还有push.default选项,请参考。

无论如何,如果你将来遇到向非裸仓库推送的问题,那么你也需要了解相关内容。


是的,抱歉,我上面应该更明确一些。我也尝试过这个方法,但我得到了错误信息,我已经在问题上附加了(无法放在评论中)。 - Coder
就像我说的那样,你需要一个裸仓库来明智地完成这个任务。 - Eli Barzilay
这是我第一次使用BitBucket进行结帐时发生的事情。非常感谢! - Valter Silva

4
如果您仍然想要推送到远程非裸库的已检出分支,现在是可能的(Git 2.3.0,2015年2月),前提是目标工作树中没有修改的文件。
在该远程库中,请执行以下操作:
git config receive.denyCurrentBranch updateInstead

它比配置receive.denyCurrentBranch=ignore更安全:只有在没有覆盖正在进行的修改时,它才允许推送。

请参见提交1404bcb Johannes Schindelin (dscho)

receive-pack: 添加另一个选项用于 receive.denyCurrentBranch

在工作目录之间进行同步时,通过“push”更新当前分支而不是“pull”可能很方便,例如当从虚拟机中推送修复或从用户的计算机上推送修复(在此情况下,开发人员甚至不能知道用户的密码,更不用说安装ssh daemon了)。

这个补丁使通常的解决方法——将代码推送到临时分支然后在其他机器上合并——变得不再必要。

新选项是:

updateInstead

根据工作树更新内容,但如果存在未提交的更改,则拒绝执行。

kd4ttc评论中所述:

这里的想法是,当您远程更新分支时,通常不应能够将其推回。
从服务器上拉取并进行更改的其他人将不知道他们独立工作时发生了哪些更改。

但是,如果只有您关心的话,这个问题就不那么严重了。
清理的方法是从存储库中拉取,然后创建一个分支:您可以随意编辑。

将来的某个时候,您会登录服务器并执行合并操作。

此选项updateInstead用于需要立即更改文件的情况。


对于像我这样的学习者,这里的想法是,如果你远程更新了一个分支,通常不应该能够将其推回。从服务器上拉取并进行更改的其他人将不知道他们独立工作时发生了什么更改。然而,如果只有你自己,这个问题就不那么重要了。干净的做法是从存储库中拉取,然后创建一个分支。你可以随心所欲地编辑它。在未来的某个时候,你可以登录服务器并进行合并。这个选项“updateInstead”是用于当你想要立即更改文件时的情况。 - kd4ttc
1
@kd4ttc 感谢您的评论:我已将其添加到答案中以增加可见性。 - VonC

0
正如错误信息所述,您正在尝试推送到的分支(master)已在origin存储库中检出。您可以通过转到o:/repository并检出不同的分支来解决此问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接