A bare repository in Git just contains the version control information and no working files (no tree) and it doesn’t contain the special .git sub-directory. Instead, it contains all the contents of the .git sub-directory directly in the main directory itself. In Git (from version 1.7.0 and above) the repository has to be bare (no working files) in order to accept a push. Bare repositories exist in Git as a way of having a central (mainly remote) repository that a number of people can push to. If you want to transfer changes from a non-bare repository to another, the correct way is to pull from the destination rather than push from the target.
In Git you should only use a bare repository to clone and pull from, and push to. It doesn’t have a checked out tree, so it just does what the “server” notionally does in a centralized VCS – records commits, branches, etc when you push to it, and gives you the latest versions when you clone or pull from it.
A non-bare git repository is a directory that contains:
- Project directories and files (the “working tree” mentioned above)
- A single directory called .git containing all of git’s administrative and control files
When you do a git status inside such a directory, git looks inside the .git directory, compares your current working tree with the “current branch” as recorded in the .git directory, and tells you what files have changed.