3

I'm on mac and trying "git push" to a local repo simulator directory:

mkdir ~/gitremote
cd ~/gitremote
git init --bare

Then in another directory:

git clone /Users/trosky/gitremote
vi readme (add one line)
git add .
git commit -m "1st file"
git push -u origin master

Counting objects: 2, done.
Writing objects: 100% (2/2), 211 bytes | 0 bytes/s, done.
Total 2 (delta 0), reused 0 (delta 0)
To /Users/trosky/gitremote/
   c0a3498..ff5511b  master -> master
Branch master set up to track remote branch master from origin.

Everything seems OK. But under ~/gitremote:

$ls
HEAD        config      hooks       objects
branches    description info        refs

Seems the "readme" file is not uploaded at all. I tried this test several times, always same issue. What happen when I can successfully git push to master, while the "remote" repo doesn't have anything.

aynber
  • 22,380
  • 8
  • 50
  • 63
Troskyvs
  • 7,537
  • 7
  • 47
  • 115
  • 1
    Possible duplicate of [git push new file to a bare repo failed: "error: src refspec master does not match any." Why?](http://stackoverflow.com/questions/41326402/git-push-new-file-to-a-bare-repo-failed-error-src-refspec-master-does-not-mat) – mychalvlcek Dec 26 '16 at 08:08
  • You're probably not pushing where you think...by the way, what is the reason for the bare repository? – Tim Biegeleisen Dec 26 '16 at 08:09

2 Answers2

6

Git doesn't push files. For that matter, repositories don't store files either—not directly, anyway (but see the next few paragraphs). Repositories store commits, and git pushes commits.

The whole point of a --bare clone is to avoid having any files, so that there are no files to get in the way of the commits. If you did have files there, they could prevent updating commits.

You might wonder: what good is a system that has no files? Indeed, it would be no good at all, so repositories store commits, and each commit represents a snapshot of an entire directory-tree full of files. You can then direct Git to extract any commit from the set of all commits saved in the repository.

Now, if and when you do direct Git to extract some commit—to make a directory full of every file that was saved in that particular commit—you need to give Git a place to put those files. A normal, non---bare repository has one distinguished place for this, called a work-tree (or sometimes working-tree or similar). This work-tree lets you view all the files, change them, add new files, remove files, and then make a new commit from the result.

In other words, the work-tree is where you do your work.

If you're doing your work in your work-tree, and someone else pushes a commit to your repository, and that new commit is used to replace your work-tree with their committed tree, what happens to all of your work? It would all be lost! So Git generally refuses a push to your repository when your repository has a work-tree.1

Hence, Git provides the bare repository. A bare repository is one with no work-tree. With no work-tree, no one can do work in it, so push won't lose work. It thus serves as a place you can always push to safely. That's all, but that's pretty important.

If you want to see the commits (and their files) that were pushed to the bare repository, you can make a non-bare clone, and fetch from the pushed-to repository, into the non-bare clone, and then check out the commit in question. This will replace your work with their work2—but since you said "do it now" you must mean that, rather than having your work rudely overwritten by their work just because they happened to push now.

As implied by the footnotes, there are lots of caveats and adjustments to this, but that's the basic setup. A bare clone is purely for pushing into, and non-bare clones are where you do your work.


1In fact, it's only when pushing to the current branch, and even then it's controllable.

2The usual git checkout also tries to make sure you don't lose any of your own work that you have not saved. You can tell it to "force" overwrite your own work, or use git reset --hard to discard your own work first, and there are plenty of complicated edge cases here, but Git generally treats all committed data as permanent and indelible. Work-tree data is much less so.

torek
  • 448,244
  • 59
  • 642
  • 775
2

Your commit has been recorded successfully in the gitremote repository. Try to clone again the repo and you will see the "1st file" commit.

Lino
  • 5,084
  • 3
  • 21
  • 39