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

发布于 2024-09-01 04:39:14 字数 2130 浏览 5 评论 0 原文

昨天,我发布了一个关于如何从我的一个仓库克隆 Git 存储库的问题机器到另一台机器,我怎样才能“git”从另一台机器克隆?

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

但是,当我对文件进行编辑、git commit -a -m "test"git Push 时,我在目标位置 (192.168.1.1) 上收到此错误):

git push                                                
[email protected]'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://[email protected]/media/LINUXDATA/working
! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'git+ssh://[email protected]/media/LINUXDATA/working'

我使用两个不同版本的 Git(远程计算机上为 1.7,本地计算机上为 1.5)。这是一个可能的原因吗?

Yesterday, I posted a question on how to clone a Git repository from one of my machines to another, How can I 'git clone' from another machine?.

I am now able to successfully clone a Git repository from my source (192.168.1.2) to my destination (192.168.1.1).

But when I did an edit to a file, a git commit -a -m "test" and a git push, I get this error on my destination (192.168.1.1):

git push                                                
[email protected]'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://[email protected]/media/LINUXDATA/working
! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'git+ssh://[email protected]/media/LINUXDATA/working'

I'm using two different versions of Git (1.7 on the remote and 1.5 on the local machine). Is that a possible reason?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

女皇必胜 2024-09-08 04:39:15

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

git checkout --detach

这似乎是 Git - 我正在使用 git 版本 1.7.7.4。

I like the idea of still having a usable repository on the remote box, but instead of a dummy branch, I like to use:

git checkout --detach

This seems to be a very new feature of Git - I'm using git version 1.7.7.4.

握住我的手 2024-09-08 04:39:15

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

在存储库中,您按下键入:

git config receive.denyCurrentBranch ignore

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

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

git checkout -f

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

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

I had the same issue. For me, I use Git push to move code to my servers. I never change the code on the server side, so this is safe.

In the repository, you are pushing to type:

git config receive.denyCurrentBranch ignore

This will allow you to change the repository while it's a working copy.

After you run a Git push, go to the remote machine and type this:

git checkout -f

This will make the changes you pushed be reflected in the working copy of the remote machine.

Please note, this isn't always safe if you make changes on in the working copy that you're pushing to.

溺渁∝ 2024-09-08 04:39:15

你可能做了什么导致了这种情况:

当你去敲一个小程序时,就会发生这种情况。你即将改变一些已经有效的东西,所以你施展了你的 3 级永久不可撤销咒语:

machine1:~/proj1> git init

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

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

,它克隆了,一切看起来都很好,所以您在 machine2 上处理代码。

然后...您尝试从 machine2 推送提交,并在标题中收到警告消息。

出现此消息的原因是因为您从中提取的 git 存储库旨在仅用于 machine1 上的该文件夹。您可以克隆它,但推送可能会导致问题。在两个不同位置管理代码的“正确”方法是使用“裸”存储库,就像建议的那样。裸存储库并不是为了在其中完成任何工作而设计的,它的目的是协调来自多个源的提交。这就是为什么评分最高的答案建议在执行 git config --bool core.bare true删除除 .git 文件夹之外的所有文件/文件夹。

澄清评分最高的答案:对该答案的许多评论都说“我没有从 machine1 中删除非 .git 文件,但我仍然能够从 machine2 提交”。这是正确的。然而,这些其他文件现在已经完全与 git 存储库“分离”了。去尝试 git status ,你应该看到类似“致命:此操作必须在工作树中运行”的内容。因此,删除文件的建议并不能让 machine2 的提交起作用;这样您就不会感到困惑并认为 git 仍在跟踪这些文件。但是,如果您仍想处理 machine1 上的文件,删除文件就会出现问题,不是吗?

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

取决于您计划在 machine1 和 machine2 上继续工作多少...

如果您完成了 machine1 的开发并将所有开发转移到machine2... 只需按照最受好评的答案建议的操作:git config --bool core.bare true 然后,可以选择删除除 .git 之外的所有文件/文件夹文件夹,因为它们未被跟踪并且可能会引起混乱。

如果您在 machine2 上的工作只是一次性的,并且您不需要在那里继续开发...那么就不必费心制作一个裸仓库;只是 ftp/rsync/scp/等。将计算机*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

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

What you probably did to cause this:

This kind of thing happens when you go to bang out a little program. You're about to change something which was already working, so you cast your level-3 spell of perpetual undoability:

machine1:~/proj1> git init

and you start adding/committing. But then, the project starts getting more involved and you want to work on it from another computer (like your home PC or laptop), so you do something like

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

and it clones and everything looks good, and so you work on your code from machine2.

Then... you try to push your commits from machine2, and you get the warning message in the title.

The reason for this message is because the git repo you pulled from was kinda intended to be used just for that folder on machine1. You can clone from it just fine, but pushing can cause problems. The "proper" way to be managing the code in two different locations is with a "bare" repo, like has been suggested. A bare repo isn't designed to have any work being done in it, it is meant to coordinate the commits from multiple sources. This is why the top-rated answer suggests deleting all files/folders other than the .git folder after you git config --bool core.bare true.

Clarifying the top-rated answer: Many of the comments to that answer say something like "I didn't delete the non-.git files from the machine1 and I was still able to commit from machine2". That's right. However, those other files are completely "divorced" from the git repo, now. Go try git status in there and you should see something like "fatal: This operation must be run in a work tree". So, the suggestion to delete the files isn't so that the commit from machine2 will work; it's so that you don't get confused and think that git is still tracking those files. But, deleting the files is a problem if you still want to work on the files on machine1, isn't it?

So, what should you really do?

Depends upon how much you plan to still work on machine1 and machine2...

If you're done developing from machine1 and have moved all of your development to machine2... just do what the top-rated answer suggests: git config --bool core.bare true and then, optionally, delete all files/folders other than .git from that folder, since they're untracked and likely to cause confusion.

If your work on machine2 was just a one-time thing, and you don't need to continue development there... then don't bother with making a bare repo; just ftp/rsync/scp/etc. your files from machine*2* on top of the files on machine*1*, commit/push from machine*1*, and then delete the files off of machine*2*. Others have suggested creating a branch, but I think that's a little messy if you just want to merge some development you did on a one-time basis from another machine.

If you need to continue development on both machine1 and machine2... then you need to set things up properly. You need to convert your repo to a bare, then you need to make a clone of that on machine1 for you to work in. Probably the quickest way to do this is to do

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

Very important: because you've moved the location of the repo from proj1 to proj1.git, you need to update this in the .git/config file on machine2. After that, you can commit your changes from machine2. Lastly, I try to keep my bare repos in a central location, away from my work trees (i.e. don't put 'proj1.git' in the same parent folder as 'proj1'). I advise you to do likewise, but I wanted to keep the steps above as simple as possible.

一张白纸 2024-09-08 04:39:15

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

在您的远程服务器上:

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

好的,从您的本地分支:

git push origin master:master

You can recreate your server repository and push from your local branch master to the server master.

On your remote server:

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

OK, from your local branch:

git push origin master:master
瞄了个咪的 2024-09-08 04:39:15

通过几个设置步骤,您可以使用像“Which is beautiful and simple”这样的单行代码轻松地将更改部署到您的网站

git push production

,并且您无需登录远程服务器并执行拉取或任何操作。请注意,如果您不使用生产结帐作为工作分支,这将效果最好! (OP 在稍微不同的上下文中工作,我认为 @Robert Gould 的解决方案很好地解决了这个问题。该解决方案更适合部署到远程服务器。)

首先,您需要在服务器上的某个位置设置一个裸存储库,位于外部您的网络根目录。

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 [email protected]:mywebsite.git
git push production +master:refs/heads/master

一切就绪!现在,将来您可以使用 git Push Production 来部署您的更改!

此解决方案的功劳归功于 http://sebduggan.com/blog/部署您的网站更改使用-git/。在那里查找有关正在发生的事情的更详细解释。

With a few setup steps you can easily deploy changes to your website using a one-liner like

git push production

Which is nice and simple, and you don't have to log into the remote server and do a pull or anything. Note that this will work best if you don't use your production checkout as a working branch! (The OP was working within a slightly different context, and I think @Robert Gould's solution addressed it well. This solution is more appropriate for deployment to a remote server.)

First you need to set up a bare repository somewhere on your server, outside of your webroot.

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

Then create file hooks/post-receive:

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

And make the file executable:

chmod +x hooks/post-receive

On your local machine,

git remote add production [email protected]:mywebsite.git
git push production +master:refs/heads/master

All set! Now in the future you can use git push production to deploy your changes!

Credit for this solution goes to http://sebduggan.com/blog/deploy-your-website-changes-using-git/. Look there for a more detailed explanation of what's going on.

彻夜缠绵 2024-09-08 04:39:15

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

You should only be pushing to a bare repository. A bare repository is a repository that has no checked out branches. If you were to cd to a bare repository directory, you'd only see the contents of a .git directory.

泛滥成性 2024-09-08 04:39:15

检查目标项目中的 .git/config

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

如果 core. bare 为 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 < [email protected]>
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

Check your .git/config in the destination project:

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

If the core. bare is false, you can set it to true:

$ git config core.bare true

and then in your local push to remote:

git push remote_repo   // suppose the destination repo is remote_repo

it will success, in the remote_repo you can check git version.

$ git log -1
commit 0623b1b900ef7331b9184722a5381bbdd2d935ba
Author: aircraft < [email protected]>
Date:   Thu May 17 21:54:37 2018 +0800

and now you can not use git in your "workspace":

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

you should set bare.bare back to false.

$ git config core.bare false
來不及說愛妳 2024-09-08 04:39:15

您有 3 个选项

  1. 再次拉动和推送:

    git pull; git 推送
    
  2. 推送到不同的分支:

    git push origin master:foo
    

    并在远程合并它(通过 gitpull-request)

    git merge foo
    

  3. 强制执行(不推荐,除非您故意通过rebase更改提交):

    git Push origin master -f
    

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

    git config receive.denyCurrentBranch 忽略
    

You have 3 options

  1. Pull and push again:

    git pull; git push
    
  2. Push into different branch:

    git push origin master:foo
    

    and merge it on remote (either by git or pull-request)

    git merge foo
    
  3. Force it (not recommended unless you deliberately changed commits via rebase):

    git push origin master -f
    

    If still refused, disable denyCurrentBranch on remote repository:

    git config receive.denyCurrentBranch ignore
    
装迷糊 2024-09-08 04:39:15

事实上,将远程设置为非签出分支就足够了。在不同的分支中签出遥控器后,您可以推送。

In fact, set the remote to a non-checked out branch is sufficient. After you checked out your remote in a different branch, you can push.

苏璃陌 2024-09-08 04:39:15

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

Android 存储库上的 git Push origin master 对我来说失败,并出现与 @hap497 相同的错误消息,因为推送到存储库 + 工作副本的非裸签出。

笔记本电脑存储库上的 git pull droid master 和工作副本对我有用。当然,您之前需要运行过类似 git Remote add droid /media/KINGSTON4GB/notes_repo/ 的命令。

I had the same problem using Git to synchronise repositories on my Android phone and laptop. The solution for me was to do a pull instead of a push, as @CharlesBailey suggested.

git push origin master on the Android repository fails for me with the same error messages that @hap497 got because of a push to a nonbare checkout of a repository + working-copy.

git pull droid master on the laptop repository and working-copy works for me. Of course, you need to have previously run something like git remote add droid /media/KINGSTON4GB/notes_repo/.

橪书 2024-09-08 04:39:15

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

事实证明,允许这样做是一件非常令人困惑的事情。所以他们添加了你看到的警告消息,这也非常令人困惑。

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

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

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

Repo2 - 将仅用于开发

设置 Repo1 如下

创建共享工作的分支。

git branch shared_branch

为了安全起见,您还应该创建一个 $(REPO).git/hooks/update 来拒绝对共享分支以外的任何内容进行任何更改,因为您不希望人们破坏您的私有分支。

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.defaultupstream才能使git Push工作)

现在您可以使用以下命令创建repo2

git clone path/to/repo1 repo2 
git checkout shared_branch 

此时您同时拥有了repo1和repo2设置为在从 repo1 中的 shared_branch 推送和拉取的本地分支上工作,无需担心该错误消息或工作目录在 repo1 中不同步。无论您使用什么正常工作流程都应该有效。

Older versions of Git used to allow pushes to the currently checked out branch of a non-bare repository.

It turns out this was a terribly confusing thing to allow. So they added the warning message you see, which is also terribly confusing.

If the first repository is just acting as a server then convert it to a bare repository as the other answers recommend and be done with it.

If however you need to have a shared branch between two repos that are both in use you can achieve it with the following setup

Repo1 - will act as the server and also be used for development

Repo2 - will be for development only

Setup Repo1 as follows

Create a branch to share work on.

git branch shared_branch

To be safe, you should also create a $(REPO).git/hooks/update that rejects any changes to anything other than shared_branch, because you don't want people mucking with your private branches.

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

Now create a local branch in repo1 where you will do your actual work.

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'

(may need to git config --global push.default upstream in order for git push to work)

Now you can create repo2 with

git clone path/to/repo1 repo2 
git checkout shared_branch 

At this point you have both repo1 and repo2 setup to work on local branches that push and pull from shared_branch in repo1, without needing to worry about that error message or having the working directory get out of sync in repo1. Whatever normal workflow you use should work.

李白 2024-09-08 04:39:15

好吧,如果你想要一个普通的远程存储库,那么创建一个额外的分支并检查它。将其推送到一个分支(未签出),并在从本地推送后将其与当前处于活动状态的分支合并。

例如,在远程服务器上:

git branch dev
git checkout dev

在本地设置上:

git push 

在远程服务器上:

git merge dev

OK, in case you want a normal remote repository, then create an extra branch and check it out. Push it into one branch (which is not checked out) and merge it with one which is currently active later after pushing from locally.

For example, on a remote server:

git branch dev
git checkout dev

On the local setup:

git push 

On remote server:

git merge dev
吃不饱 2024-09-08 04:39:15

您可以执行以下一项测试来了解服务器内容的工作原理:

假设您有一台工作站和一台服务器,其中托管了实时站点,并且您希望随时更新此站点到时间(这也适用于两个开发人员通过一个纯粹的中间人来回发送他们的工作的情况)。

初始化

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

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

工作流程

现在这是基本工作流程:

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

    # 创造疯狂的东西
    git 提交-av
    git推送原点大师
    
  2. 现在进入content目录并更新服务器的内容:

    <前><代码>git pull

  3. 重复1-2。这里的内容可能是另一个开发人员,也可以推送到服务器,并且本地,因为您可以从他那里拉取。

Here is one test you can do to see how the bare server stuff work:

Imagine you have a workstation and a server with live site hosted on it, and you want to update this site from time to time (this also applies to a situation where two developers are sending their work back and forth through a bare middleman).

Initialization

Create some directory on your local computer and cd into it, then execute these commands:

# initialization
git init --bare server/.git
git clone server content
git clone server local
  1. First you create a bare server directory (notice the .git at the end). This directory will serve as a container for your repository files only.
  2. Then clone your server repository to a newly created content directory. This is your live/production directory which will be served by your server software.
  3. The first two directories resides on your server, the third one is a local directory on your workstation.

Workflow

Now here is the basic workflow:

  1. Enter the local directory, create some files and commit them. Finally push them to the server:

    # create crazy stuff
    git commit -av
    git push origin master
    
  2. Now enter the content directory and update the server's content:

    git pull
    
  3. Repeat 1-2. Here content may be another developer that can push to the server too, and local as you may pull from him.

忘年祭陌 2024-09-08 04:39:15

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

git push <remote> master:origin/master

远程无法访问上游存储库,因此这是获取该远程最新更改的好方法

Using this to push it to the remote upstream branch solved this issue for me:

git push <remote> master:origin/master

The remote had no access to the upstream repo so this was a good way to get the latest changes into that remote

妄想挽回 2024-09-08 04:39:15

我必须在现有的裸存储库中重新运行 git --init ,这在裸存储库树中创建了一个 .git 目录 - 我意识到在输入 <代码>git status在那里。我删除了它,一切都很好:)

(所有这些答案都很棒,但就我而言,这是完全不同的东西(据我所知),如所描述的。)

I had to re-run git --init in an existing bare repository, and this had created a .git directory inside the bare repository tree - I realized that after typing git status there. I deleted that and everything was fine again :)

(All these answers are great, but in my case it was something completely different (as far as I can see), as described.)

冷月断魂刀 2024-09-08 04:39:15

我确信大多数人看到这个问题都会停在前两个巨大的答案上,但我仍然想提供我的解决方案。

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

I'm sure most people viewing this question will stop at the first two huge answers, but I'd still like to offer my solution.

I had an Eclipse + EGit web project setup when encountering the described error. What helped me was simply using the GitHub app, which seemed to magically resolve the issue. While EGit would always refuse the push, the GitHub desktop app would just shrug its shoulders and push my changes. Maybe it handles the multi-login-situation more gracefully.

人│生佛魔见 2024-09-08 04:39:15

我发现对其他人可能有用的一篇文章是 Git in 5 分钟

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

我读到的有关 Git 的文章都没有谈到裸存储库。这一切听起来都很简单,直到我尝试了我认为从 SVN 背景应该很容易的事情。

这里的建议使远程存储库裸露工作。更符合我的要求的是将 Xcode 项目克隆到 projectname.git,然后将其复制到远程服务器;然后推动就神奇地起作用了。下一步将是让 Xcode 推送时不会出现提交错误,但现在我可以从终端进行操作。

因此:

cd /tmp (or another other directory on your system)<br/>
git clone --bare /xcode-project-directory projectname.git<br/>
scp -r projectname.git [email protected]:repos/<br/>

在 Xcode 中提交后,要从 Xcode 项目推送更改:

cd /xcode-project-directory<br/>
git push [email protected]:repos/projectname.git<br/>

我确信有一种更流畅、更复杂的方法可以完成上述操作,但至少这是可行的。为了让一切都清楚,这里有一些澄清:
/xcode-project-directory 是您的 xcode 项目存储的目录。它可能是 /Users/Your_Name/Documents/Project_Name
项目名称实际上是项目的名称,但它可以是您喜欢的任何名称。 Git 不在乎,你会在乎。

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

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

An article I found that might be useful to others is Git in 5 minutes.

I had an Xcode project under Git version control that I wanted to push up to a Virtual Distributed Ethernet (VDE) I have in a DC. The VDE runs Centos 5.

None of the articles I read about Git talked about bare repositories. It all sounded so simple until I tried what I thought should be easy coming from an SVN background.

The suggestions here to make the remote repository bare worked. Even better for my requirements was to clone the Xcode project to projectname.git, copy that to the remote server; then pushes magically worked. The next step will be getting Xcode to push without errors about commits, but for now I'm okay doing it from Terminal.

So:

cd /tmp (or another other directory on your system)<br/>
git clone --bare /xcode-project-directory projectname.git<br/>
scp -r projectname.git [email protected]:repos/<br/>

To push changes from your Xcode project after you've committed in Xcode:

cd /xcode-project-directory<br/>
git push [email protected]:repos/projectname.git<br/>

I'm certain there is a smoother more sophisticated way of doing the above, but at a minimum this works. Just so everything is clear, here are some clarifications:
/xcode-project-directory is the directory your xcode project is stored in. It's probably /Users/Your_Name/Documents/Project_Name.
projectname is literally the name of the project, but it can be anything you care to call it. Git doesn't care, you will.

To use scp you need to have a user account on the remote server that's allowed SSH access. Anyone running their own server will have this. If you're using shared hosting or the like, you might be out of luck.

remotehost.com is the name of your remote host. You could as easily use its IP address. Just for further clarity I'm using Gitosis on the remote host with SSH keys, so I'm not prompted for passwords when I push. The article Hosting Git Repositories, the Easy (and Secure) Way tells you how to set all that up.

迟到的我 2024-09-08 04:39:15

最好的方法是:

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

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

然后从本地 Git 存储库:

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

进行更改后,您可以:

git push remoterepo master

The best way to do this is:

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

This will clone the repository, but it won't make any working copies in .../remote. If you look at the remote, you'll see one directory created, called currentrepo.git, which is probably what you want.

Then from your local Git repository:

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

After you make changes, you can:

git push remoterepo master
吃颗糖壮壮胆 2024-09-08 04:39:15

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

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

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

重置:

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

    heroku 插件:安装 https://github.com/heroku/heroku-repo.git
    
  3. 执行重置,这将删除存储库并创建一个新的空存储库

    heroku 仓库:重置
    
  4. 像平常一样推送到 Heroku 远程;它将重新上传所有内容。

I just ran into this problem with a deployment git repository on Heroku.

I don't know why Heroku has a non-bare repository on their side, but as a workaround I was able to reset the remote repository, and reupload.

You shouldn't use Heroku's copy of your repository as your only git repository for collaboration, but just in case, I'll say clearly: Do not do this unless you are sure you have a full copy of your repository stored securely somewhere other than Heroku. Doing a reset will delete the repository contents.

To reset:

  1. Install the Heroku toolbelt (which contains the command line client) if you haven't already.
  2. Install the heroku-repo plugin if you haven't already.

    heroku plugins:install https://github.com/heroku/heroku-repo.git
    
  3. Do the reset, which deletes the repository and creates a new, empty one

    heroku repo:reset
    
  4. Push to your Heroku remote as you normally would; it will reupload everything.

伴随着你 2024-09-08 04:39:15

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

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 分支未知,您应该将 bare 更改为 true,推送成功后您可以重用,

git remote show origin

您将看到

 HEAD branch: master

You will need to change the config file on the remote server once you have created empty(bare) repository, say

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

there you will see

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

You will make this bare to false to true and I removed logallrefupdates = true (not sure of its use!)

to

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

You may test following

$ 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)

This HEAD branch: (unknown) will be shown if you are unable to PUSH. So if the HEAD branch is unknow, you should change bare to true and after push successful you can reuse the

git remote show origin

and you will see

 HEAD branch: master
没有你我更好 2024-09-08 04:39:15

如果您使用 SSH 密钥连接到 github,请确保您的 SSH 密钥仍在您的个人资料设置下。由于某种原因,我的密钥在那里被清除,我无法推送到我的主分支。我所做的只是再次将 SSH 密钥添加到 settings/SSH keys 中。

输入图片此处描述

查看现有密钥的命令:cat ~/.ssh/id_rsa.pub

If you are using SSH key to connect into github, make sure that your SSH key is still there under your profile settings. For some reason, my key was cleared there and I couldn't push to my master branch. What I did is I just added my SSH key to settings/SSH keys again.

enter image description here

Command to view your existing key: cat ~/.ssh/id_rsa.pub

她比我温柔 2024-09-08 04:39:15

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

在远程:

git checkout -b some_tmp_name

在本地:

git push

在远程:

git checkout master
git branch -d some_tmp_name

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

For me working solution is:

ON REMOTE:

git checkout -b some_tmp_name

ON LOCAL:

git push

ON REMOTE:

git checkout master
git branch -d some_tmp_name

But this is not the real solution it's just workaround.

◇流星雨 2024-09-08 04:39:15

以防万一有人发现它有用。对我来说这是一个 git 服务器权限问题。我从一开始就检查了该项目并推送了一个简单的文件,然后我得到了“推送被拒绝:推送到 origin/master 被拒绝”

Just in case someone finds it useful. For me it was a git server permissions issue. I checked out the project from the beggining and push a simple file and then I got the "Push rejected: Push to origin/master was rejected"

堇色安年 2024-09-08 04:39:15

让我加 50 美分,因为投票最多的答案 https://stackoverflow.com/a/3251126/3455918 建议将远程repw转换为裸存储库,如果这不是我想要的怎么办?

最后,我必须在远程计算机上拥有相同的代码,而不仅仅是 .gitlimbo 中某处的字节块。

第二次投票的(截至撰写本文时)解决方案 https://stackoverflow.com/a/2933656/3455918 执行以下操作:工作,但经过测试后,我最终不得不不断地在远程计算机上的分支之间切换,以“释放”我想要从本地计算机推送到的分支。

这对我有用:

到目前为止对我有用的另一个解决方案不是我的,归功于对第一个解决方案发表评论的用户@kxr。

在远程计算机上,您必须在 repo 目录中执行此命令。

git config receive.denyCurrentBranch updateInstead

之后你就完成了!

显然,此解决方案可能存在一些缺点,但对于将本地机器代码同步到远程存储库的简单任务来说,它可能已经足够好了。

如果有人在评论中解释为什么在 github 上创建一个全新的存储库、将本地文件夹链接到它并开始执行 git Push origin master 且没有错误是完全可以的,我将不胜感激。

但是尝试使用远程服务器上的存储库进行同样的操作会产生错误:

! [远程拒绝]master-> master(分支当前已签出)

Let me add my 50 cents, because the most voted answer https://stackoverflow.com/a/3251126/3455918 suggests a converting of remote repw to a bare repository, and what if it's not what I want?

In the end I have to have the same code on the remote machine but not just blobs of bytes somewhere in .git limbo.

The second-voted (as of this writing) solution https://stackoverflow.com/a/2933656/3455918 does the job but after testing this out I ended up having to constantly switch between branches on the remote machine to "free" the branch I want to push from my local machine to.

This worked for me:

Another solution that worked for me so far is not mine, credit is given to a user @kxr who commented on the first solution.

On the remote machine you have to make this command in the repo directory.

git config receive.denyCurrentBranch updateInstead

After this you are done!

Obviously, there might be some drawbacks of this solution but for a simple task of synchronizing your local machine code to your remote repo it's probably good enough.

I would be grateful if someone explaines in comments why it's totally fine to create a brand new repo on github, link your local folder to it and start doing git push origin master without errors.

But trying to make this same thing with the repo on the remote server yields and error:

! [remote rejected] master -> master (branch is currently checked out)

天煞孤星 2024-09-08 04:39:14

错误消息 error: refusing to updateChecked out Branch: refs/heads/master 是由远程存储库发出的,这意味着您正在尝试将代码推送到具有不同代码的远程非裸存储库当前已在工作目录中签出。避免此问题的最佳方法是仅推送到裸存储库 - 裸存储库永远不会发生此问题。

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

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

git config --bool core.bare true

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

The error message error: refusing to update checked out branch: refs/heads/master is emitted by the remote repository and it means you're trying to push code to remote non-bare repository that has different code currently checked out in the working directory. The best way to avoid this problem is to push to bare repositories only - this problem cannot ever happen with a bare repository.

You can simply convert your remote repository to bare repository (there is no working copy in the bare repository - the folder contains only the actual repository data).

Execute the following command in your remote repository folder:

git config --bool core.bare true

Then delete all the files except .git in that folder. And then you will be able to perform git push to the remote repository without any errors.

彩虹直至黑白 2024-09-08 04:39:14

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

我将使用非技术术语来表达这个想法。无论如何,发生的情况是您有两个存储库,一个是您第一个制作的原始存储库,另一个是您刚刚制作的作品。

现在您位于工作存储库中并使用 master 分支。但您也恰好在原始存储库中“登录”到同一个 master 分支。现在,由于您已经“登录”了原始版本,Git 担心您可能会搞砸,因为您可能正在处理原始版本并将事情搞砸。因此,您需要返回到原始存储库并执行git checkout someotherbranch,现在您可以毫无问题地推送。

I just had the same error while I began learning Git. Some of the other answers are clearly not for someone new to Git!

I am going to use non technical terms to get the idea across. Anyway, what is happening is that you have two repositories, one is the original you first made, and the other the work one you just made.

Right now you are in your work repository and are using the master branch. But you also happen to be "logged in" in your original repository to the same master branch. Now since you're "logged in" in the original, Git fears you might mess up because you might be working on the original and screw things up. So you need to return to the original repository and do git checkout someotherbranch, and now you can push with no problems.

白色秋天 2024-09-08 04:39:14

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

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

  1. 始终通过拉取(或获取和合并)更新存储库,或者,如果必须,

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

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

这会很容易意外地提交一个更改,从而撤消所有已推送的更改,并且还很难区分尚未提交的任何本地更改和新< code>HEAD,推送移动HEAD引起的索引和工作树。

The error message describes what has happened. More modern versions of Git refuse to update a branch via a push if that branch is checked out.

The easiest way to work between two non-bare repositories is either to

  1. always update the repositories by pull (or fetch and merge) or, if you have to,

  2. by pushing to a separate branch (an import branch) and then merging that branch into the master branch on the remote machine.

The reason for this restriction is that the push operation operates only on the remote Git repository, it doesn't have access to the index and working tree. So, if allowed, a push on the checked-out branch would change the HEAD to be inconsistent with the index and working tree on the remote repository.

This would make it very easy to accidentally commit a change that undoes all of the pushed changes and also makes it very difficult to distinguish between any local changes that have not been committed and differences between the new HEAD, the index and the working tree that have been caused by push moving HEAD.

南城旧梦 2024-09-08 04:39:14

摘要

您无法推送到存储库的一个签出分支,因为它会以一种很可能以数据和历史记录丢失结束的方式扰乱该存储库的用户。但您可以推送到同一存储库的任何其他分支。

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

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

解决方案 1:使用裸存储库

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

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

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

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

但是如果您需要签出远程 上的代码,那么您可以使用特殊分支进行推送。假设在您的本地存储库中,您已调用远程origin并且您位于分支master上。然后你可以这样做

machine2$ git push origin master:master+machine2

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

machine1$ git merge master+machine2

问题的尸检

当签出分支时,提交将添加一个新的提交,其中当前分支的头为它的父级并将分支的头移动到新的提交。

所以

A ← B
    ↑
[HEAD,branch1]

变成了

A ← B ← C
        ↑
    [HEAD,branch1]

但是如果有人可以推送到中间的那个分支,用户就会进入 git 所谓的 detached head 模式:

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

现在用户不再在branch1中,而没有明确要求检查另一个分支。更糟糕的是,用户现在在任何分支之外,并且任何新提交都将是悬空

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

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

Summary

You cannot push to the one checked out branch of a repository because it would mess with the user of that repository in a way that will most probably end with loss of data and history. But you can push to any other branch of the same repository.

As bare repositories never have any branch checked out, you can always push to any branch of a bare repository.

There are multiple solutions, depending on your needs.

Solution 1: Use a Bare Repostiory

As suggested, if on one machine, you don't need the working directory, you can move to a bare repository. To avoid messing with the repository, you can just clone it:

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

Now you can push all you want to the same address as before.

Solution 2: Push to a Non-Checked-Out Branch

But if you need to check out the code on your remote <remote>, then you can use a special branch to push. Let's say that in your local repository you have called your remote origin and you're on branch master. Then you could do

machine2$ git push origin master:master+machine2

Then you need to merge it when you're in the origin remote repo:

machine1$ git merge master+machine2

Autopsy of the Problem

When a branch is checked out, committing will add a new commit with the current branch's head as its parent and move the branch's head to be that new commit.

So

A ← B
    ↑
[HEAD,branch1]

becomes

A ← B ← C
        ↑
    [HEAD,branch1]

But if someone could push to that branch inbetween, the user would get itself in what git calls detached head mode:

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

Now the user is not in branch1 anymore, without having explicitly asked to check out another branch. Worse, the user is now outside any branch, and any new commit will just be dangling:

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

Hypothetically, if at this point, the user checks out another branch, then this dangling commit becomes fair game for Git's garbage collector.

眉目亦如画i 2024-09-08 04:39:14

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

[receive]
denyCurrentBranch = warn

或者

[receive]
denyCurrentBranch = false

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

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

You can get around this "limitation" by editing the .git/config on the destination server. Add the following to allow a git repository to be pushed to even if it is "checked out":

[receive]
denyCurrentBranch = warn

or

[receive]
denyCurrentBranch = false

The first will allow the push while warning of the possibility to mess up the branch, whereas the second will just quietly allow it.

This can be used to "deploy" code to a server which is not meant for editing. This is not the best approach, but a quick one for deploying code.

冬天的雪花 2024-09-08 04:39:14

git config --local receive.denyCurrentBranch updateInstead

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

在服务器存储库上使用它,它也会更新如果没有发生未跟踪的覆盖,则工作树。

它已作为

我已经编译了 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 被推了!

git config --local receive.denyCurrentBranch updateInstead

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

Use that on the server repository, and it also updates the working tree if no untracked overwrite would happen.

It was added in Git 2.3 as mentioned by VonC in the comments.

I've compiled Git 2.3 and gave it a try. Sample usage:

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

Output:

a
b

Yay, b got pushed!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文