Git push error '[remote rejected] master -> ma

2018-12-31 02:59发布

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                                                
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'

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?

标签: git git-push
30条回答
人间绝色
2楼-- · 2018-12-31 03:44

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.

查看更多
浮光初槿花落
3楼-- · 2018-12-31 03:45

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.

查看更多
闭嘴吧你
4楼-- · 2018-12-31 03:45

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 git@myserver.com: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.

查看更多
妖精总统
5楼-- · 2018-12-31 03:49

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
    
查看更多
看淡一切
6楼-- · 2018-12-31 03:49

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.

查看更多
只靠听说
7楼-- · 2018-12-31 03:50

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.

查看更多
登录 后发表回答