Search code examples
gitgit-cloneworking-copygit-non-bare-repository

Git clone prevent from cloning working copy (non bare) repository


If you do a clone of a git working copy (repository with a working tree) change some files, commit and try to push you'll get a message:

remote: error: refusing to update checked out branch: refs/heads/master
...
! [remote rejected] master -> master (branch is currently checked out)

That's understandable and wanted behavior to me.

I would like to prevent accidentally cloning a working copy of a repository.

How to prevent git clone from cloning working copies instead of remote bare repositories and signal an error in case of an attempt to clone a working copy?

Is there any command line switch that causes git clone non zero exit status in case of an attempt to clone working copy instead of a bare remote repository?

If not then how to check a repository location (url, or path to dir) if it contains a bare repository so I can test that in bash before cloning.

Please note that a working copy of a repository does not necessarily mean it is local because it can be shared by remote as well.

In my case git clone should be allowed only to work with with git bare repositories and signal an error if used to clone working copy.


Solution

  • There is no way to prevent you from cloning a repository with a working tree. When Git commits contents into a repository, they are available by accessing the .git directory or its equivalent without any inspection or manipulation of the working tree.

    This is actually extremely important for security because one of the only safe things you can do with an untrusted repository is to clone or fetch from it. If you were prevented from doing that, there would be no way to get data from untrusted repositories in a safe way.

    You can check whether a local repository has a working tree by running git rev-parse --is-bare-repository in the repository in question (or using -C). It will print true if it's bare (that is, lacks a working tree) and false if it's not. You cannot check this on a repository that is not accessible via a local file system (e.g., an HTTPS or SSH remote) because that would involve you being able to inspect the remote system's file system and it would be a security problem if remote users could do that.

    My recommendation is to not worry about this scenario too much instead of trying to fight Git on this. This behavior poses few practical problems and shouldn't typically be a cause for concern.