0

I have a linux server with ssh and git installed.

I created a folder on the root directory and changed its owner to mike to avoid giving out root passwords to anyone.

sudo mkdir /GitRepos
sudo chown mike:mike /GitRepos

Then I created an empty repo, and set it to bare, otherwise pushing to this repo does not work (I tried!!)

mkdir test.git
cd test.git
git init
git config core.bare true

I then used another machine (Windows) to clone the newly created repo:

git clone ssh://mike@myLinuxServer/GitRepos/test.git

and that worked fine, I got an empty repo as expected. I added some files and committed the change.

git add .
git commit -m "Initial commit"
git push origin master

Pushing works fine. I even deleted the entire repo from the local machine, and tried to clone it again.

cd ..
rd test /s
git clone ssh://mike@myLinuxServer/GitRepos/test.git

It worked fine and I got all of the files. When I went to the remote Linux machine, I listed the files inside test.git and found it empty. Where did the files go? How can the repo receive pushes and give out files for pulls without storing the files in the repo?

Ahmad
  • 12,336
  • 6
  • 48
  • 88
  • https://stackoverflow.com/search?q=%5Bgit%5D+difference+bare+non-bare+repositories – phd Mar 09 '20 at 08:10

2 Answers2

2

The files are stored in the remote repository's database. You cannot expect that the files themselves appear in the remote repository, in particular not when you declare it as bare.

The way you initialized the bare remote repository is very unusual. You should have done it simply like this:

cd /GitRepos
git init --bare test.git
j6t
  • 9,150
  • 1
  • 15
  • 35
2

The repository on the server is considered as a bare repo as you ran git config core.bare true. A more common way to initialize a bare repo is git init --bare test.git or mkdir test.git;cd test.git;git init --bare. The difference between git init test.git;cd test.git;git config core.bare true and git init --bare test.git lies in the directory structure. The former creates the worktree(test.git) and the database(test.git/.git) but forbids the worktree then. The latter creates only the database(test.git), without the worktree from the beginning.

A bare repository does not have an active worktree by default, which means you can't check out files from any revision in a bare repository. Although you can create extra worktrees with git worktree add, it's quite rare and may behave not so well as a non-bare repository with extra worktrees. All the revisions are stored as compressed data in the database. You can use commands to read the data, like git show master or git ls-tree -r master.

otherwise pushing to this repo does not work (I tried!!)

It's partially true. You can't push to a non-bare repository when you try to update a branch which has been checked out in the remote repository. If the branch you try to update is not checked out or does not exist yet, you can push to update or create it. With git config receive.denyCurrentBranch ignore or git config receive.denyCurrentBranch warn, you can even update such branch. But in practice, we always use bare repositories to preserve revision data.

ElpieKay
  • 27,194
  • 6
  • 32
  • 53