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

671 Views Asked by At

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.

2

There are 2 best solutions below

0
On BEST ANSWER

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.

0
On

To augment bk2204's answer, you should think of the working tree as not part of the repository ... because in a pretty strong sense, it isn't part of the repository. Since the work-tree isn't part of the repository, it never gets copied by git clone. That means there are no issues here.

(Git's index, and files copied into the index, are, at least sort of, part of the repository, but the index itself is not copied. Blob objects—file contents—that were newly stored into the Git repository, via git add, but that have not yet been committed, could potentially be copied, although in general unreferenced objects should not get copied during cloning. I am pretty sure I found instances of unreferenced objects in a fresh clone at least once, back in the Git 1.5.5 / Git 1.6-ish days. But working tree files that have never been git add-ed have no representation at all in the repository databases, and those are what are copied during cloning.)