Git repositories store the complete history of a project, including all files, commits, and changes made over time. They allow developers to track progress, manage versions, and revert to previous states when needed. Based on their usage, repositories in Git are mainly classified into two types:
- Non-bare repositories
- Bare repositories
Non-bare Repository (Default Repository)
A non-bare repository is the standard Git repository created when you run the git init command inside a project directory. It contains:
- .git folder: Stores all repository data such as commits, branches, configuration, and history.
- A working tree: The actual project files that you can view, edit, and modify.
File structure of a non-bare repository:
Default_Repo/
│
├── .git/ (* Folder)
│ ├── hooks/ (* Folder)
│ ├── info/ (* Folder)
│ ├── logs/ (* Folder)
│ ├── objects/ (* Folder)
│ ├── refs/ (* Folder)
│ ├── COMMIT_EDITMSG
│ ├── config
│ ├── description
│ ├── HEAD
│ └── index
│
└── example.txt
- Used for local development.
- You can edit, commit, and track changes.
- .git folder is the “brain” of your repository.
Bare Repository
A bare repository is different because it does not have a working tree, meaning you cannot directly modify or commit files inside it. It contains only the .git folder contents.
- Serves as a central repository for collaboration
- Acts as a “reference” for other developers to clone, push, or pull changes
- Prevents conflicts in shared development environments
Creating a Bare Repository
mkdir FileName.git && cd FileName.git && git init --bareFile structure of a bare repository:
BareRepo.git/ (* Folder)
│
├── hooks/ (* Folder)
├── info/ (* Folder)
├── logs/ (* Folder)
├── objects/ (* Folder)
├── refs/ (* Folder)
├── COMMIT_EDITMSG
├── config
├── description
├── HEAD
└── index
- Same structure as the .git directory in a non-bare repository and typically named with .git extension (e.g., Repo.git).
- No working directory, so direct commits are not possible; supports only push and clone operations.
Using a Bare Repository
Below are the steps to use the Bare Repository:
Step 1: Clone a bare repository
Create a local repository by cloning the bare repository:
cd C:/Users/example/repositories
git clone C:/Users/example/BareRepo.git
Output might show a warning:
warning: You appear to have cloned an empty repository.Step 2: Add files and commit locally
cd BareRepo
git add
git commit -m "First commit"
Step 3: Push changes to the bare repository
git push C:/Users/example/BareRepo.gitNow, your local repository is linked to the bare repository.
Converting a Local Repository to Bare
If you already have a local repository, you can clone it as bare:
cd "Central Repositories"
git clone --bare ../../path_to_local_repo
This creates LocalRepo.git as a bare repository.
Reasons to use Bare Repositories as Central Repositories
Bare repositories are suitable as central repositories for team collaboration.
- Avoids conflicts between multiple developers.
- Prevents inconsistent working tree.
- Efficient storage (only tracks .git contents).
- Recommended for remote servers.
Git does not allow pushing to a non-bare repository by default.
If you try, you’ll get an error like:
remote: error: refusing to update checked out branch: refs/heads/masterYou can bypass it by changing settings (receive .deny Current Branch ignore), but this can create inconsistencies between the working tree and commits.
Non-bare Repository (Local) Vs Bare Repository (Central/Remote)
A non-bare repository contains a working directory for development, while a bare repository stores only Git data and is used as a central repository for collaboration.
| Non-bare Repository (Local) | Bare Repository (Central/Remote) |
|---|---|
| Contains a working tree with project files | No working tree, only repository data |
| Direct commits are allowed | Direct commits are not allowed |
| Used for local development and editing code | Used as a central repository for collaboration |
| Structure includes .git folder + project files | Structure contains only .git contents |
| Can pull from remote and push changes | Mainly accepts push and allows cloning |