michael
michael

Reputation: 110620

How to fix error when git push was rejected

I have started git by first clone a repository and then 'git commit' but when i do 'git push' I am getting this error: But it said 'refusing to update checkout branch'?

$ git push
Counting objects: 17, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (13/13), done.
Writing objects: 100% (13/13), 2.72 KiB, done.
Total 13 (delta 5), reused 0 (delta 0)
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 ssh://[email protected]/home/michae/scripts
 ! [remote rejected] master -> master (branch is currently checked out)

what does this mean?

I search and read How to cope with "rejected" on git push?

I even try 'git push origin HEAD' that gives me same error:

Upvotes: 2

Views: 2718

Answers (3)

Brian Campbell
Brian Campbell

Reputation: 333086

There are two types of Git repositories: bare and non-bare. A bare repository just contains the commits, branches, tags, and so on; a non-bare repository also contains a current working copy. If you look at a repository, you can tell if it's bare. If you have a directory containing the files in your project, as well as a .git directory, that's a non-bare repository; those files outside of the .git directory are the current working copy. If you have just the contents of the repository, such as refs, objects, and so on, that's a bare repository. It has no working copy.

You can only push to bare repositories (unless you override the default configuration). You can pull from a non-bare repository, and pull into a non-bare repository, but you cannot push into one. This is to prevent problems updating the working copy. The working copy is a copy of your current state; you may have edited files, and so on. When you pull into a repository, the latest changes are checked out into your working copy; if you have some local changes that aren't checked in, they are merged with the changes from the repository you're pulling from, or the checkout is rejected and you need to fix up your local copy to be able to check out those new changes.

On a repository you are pushing to, you are not able to immediately make changes if there's a conflict. The working tree will instead get out of date; what's in the repo and what's in the working tree will be out of sync. To prevent this, Git refuses to let you push into a non-bare repo.

It's recommended to use a bare repo as your "central" repo, that you push to and pull from, use a non-bare repo for your working tree; where you actually do your work. Since it looks like you already have a repo that you have cloned from, you will need to create a bare repo from that, and update your origin to point to the bare repo instead of the non-bare one. You can create the bare repo with git clone --bare path/to/original/repo path/to/bare/repo.git (it's customary to name bare repos name.git). If this will be shared between multiple people on the same machine, you should also pass --shared to set up permissions correctly. Then in your working copy, run git remote set-url origin path/to/bare/repo.git, and git remote set-url --push origin path/to/bare/repo.git (or user@host:/path/to/bare/repo.git if you access it over SSH).

Upvotes: 4

gahooa
gahooa

Reputation: 137472

Perhaps you should convert the remote to a bare repo without a working copy.

ssh user@remote
cd /path/containing/repo
git clone --bare repo/ repo.git

Now, in your working repo, edit the .git/config to update the URL for the remote. Add a .git to the end of it.

[remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*
    url = user@remote:/path/to/repo.git

Then run

git push origin HEAD

to push the current branch.

Upvotes: 1

bmargulies
bmargulies

Reputation: 100153

The repository on the target is not 'bare'. That is, it has files checked out, and not just a .git database.

The convention is to use bare 'repositories' as the targets of push.

The error message tells you everything you need to know: you can change the configuration in the remote repo to permit this, or you can render it bare.

Upvotes: 2

Related Questions