What's the -practical- difference between a Bare and non-Bare repository?

118,091

Solution 1

Another difference between a bare and non-bare repository is that a bare repository does not have a default remote origin repository:

~/Projects$ git clone --bare test bare
Initialized empty Git repository in /home/derek/Projects/bare/
~/Projects$ cd bare
~/Projects/bare$ git branch -a
* master
~/Projects/bare$ cd ..
~/Projects$ git clone test non-bare
Initialized empty Git repository in /home/derek/Projects/non-bare/.git/
~/Projects$ cd non-bare
~/Projects/non-bare$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

From the manual page for git clone --bare:

Also the branch heads at the remote are copied directly to corresponding local branch heads, without mapping them to refs/remotes/origin/. When this option is used, neither remote-tracking branches nor the related configuration variables are created.

Presumably, when it creates a bare repository, Git assumes that the bare repository will serve as the origin repository for several remote users, so it does not create the default remote origin. What this means is that basic git pull and git push operations won't work since Git assumes that without a workspace, you don't intend to commit any changes to the bare repository:

~/Projects/bare$ git push
fatal: No destination configured to push to.
~/Projects/bare$ git pull
fatal: /usr/lib/git-core/git-pull cannot be used without a working tree.
~/Projects/bare$ 

Solution 2

5 years too late, I know, but no-one actually answered the question:

Then, why should I use the bare repository and why not? What's the practical difference? That would not be beneficial to more people working on a project, I suppose.

What are your methods for this kind of work? Suggestions?

To quote directly from the Loeliger/MCullough book (978-1-449-31638-9, p196/7):

A bare repository might seem to be of little use, but its role is crucial: to serve as an authoritative focal point for collaborative development. Other developers clone and fetch from the bare repository and push updates to it... if you set up a repository into which developers push changes, it should be bare. In effect, this is a special case of the more general best practice that a published repository should be bare.

Solution 3

The distinction between a bare and non-bare Git repository is artificial and misleading since a workspace is not part of the repository and a repository doesn't require a workspace. Strictly speaking, a Git repository includes those objects that describe the state of the repository. These objects may exist in any directory, but typically exist in the .git directory in the top-level directory of the workspace. The workspace is a directory tree that represents a particular commit in the repository, but it may exist in any directory or not at all. Environment variable $GIT_DIR links a workspace to the repository from which it originates.

Git commands git clone and git init both have options --bare that create repositories without an initial workspace. It's unfortunate that Git conflates the two separate, but related concepts of workspace and repository and then uses the confusing term bare to separate the two ideas.

Solution 4

A bare repository is nothing but the .git folder itself i.e. the contents of a bare repository is same as the contents of .git folder inside your local working repository.

  • Use bare repository on a remote server to allow multiple contributors to push their work.
  • Non-bare - The one which has working tree makes sense on the local machine of each contributor of your project.

Solution 5

A default/non-bare Git repo contains two pieces of state:

  1. A snapshot of all of the files in the repository (this is what "working tree" means in Git jargon)
  2. A history of all changes made to all the files that have ever been in the repository (there doesn't seem to be a concise piece of Git jargon that encompasses all of this)

The snapshot is what you probably think of as your project: your code files, build files, helper scripts, and anything else you version with Git.

The history is the state that allows you to check out a different commit and get a complete snapshot of what the files in your repository looked like when that commit was added. It consists of a bunch of data structures that are internal to Git that you've probably never interacted with directly. Importantly, the history doesn't just store metadata (e.g. "User U added this many lines to File F at Time T as part of Commit C"), it also stores data (e.g. "User U added these exact lines to File F").

The key idea of a bare repository is that you don't actually need to have the snapshot. Git keeps the snapshot around because it's convenient for humans and other non-Git processes that want to interact with your code, but the snapshot is just duplicating state that's already in the history.

A bare repository is a Git repository that does not have a snapshot. It just stores the history.

Why would you want this? Well, if you're only going to interact with your files using Git (that is, you're not going to edit your files directly or use them to build an executable), you can save space by not keeping around the snapshot. In particular, if you're maintaining a centralized version of your repo on a server somewhere (i.e. you're basically hosting your own GitHub), that server should probably have a bare repo (you would still use a non-bare repo on your local machine though, since you'll presumably want to edit your snapshot).

If you want a more in-depth explanation of bare repos and another example use case, I wrote up a blog post here: https://stegosaurusdormant.com/bare-git-repo/

Share:
118,091

Related videos on Youtube

AeroCross
Author by

AeroCross

Transforming cookies and muffins into code since 2008.

Updated on August 27, 2021

Comments

  • AeroCross
    AeroCross almost 3 years

    I've been reading about the bare and non-bare / default repositories in Git. I haven't been able to understand quite well (theoretically) the differences between them, and why I should "push" to a bare repository. Here's the deal:

    Currently, I'm the only one working on a project on 3 different computers, but there will be more people involved in it later, so I'm using Git for the version control. I clone the bare repo on all computers, and when I finish my modifications on one of them, I commit and push the changes to the bare repo. From what I've read, the bare repository does NOT have a "working tree", so if I clone the bare repo, I won't have a "working tree".

    I'm guessing that the working tree stores the commit information, branches, etc. from the project. That wouldn't appear in the bare repo. So it seems better for me to "push" the commits to the repo with the working tree.

    Then, why should I use the bare repository and why not? What's the practical difference? That would not be beneficial to more people working on a project, I suppose.

    What are your methods for this kind of work? Suggestions?

    • Derek Mahar
      Derek Mahar about 13 years
      AeroCross, you can clone a bare repository to create a non-bare repository (that is, one which has a workspace). So, using git clone you can freely convert between bare and non-bare repositories.
    • AeroCross
      AeroCross about 13 years
      @Derek I knew that I could clone a non-bare to a bare, but not the other way around. Excellent little tip.
    • Cascabel
      Cascabel about 13 years
      @AeroCross: It's not about converting; it doesn't matter what's on the other end. If you run git clone --bare you'll get a bare repo, and if you run git clone, you'll get a non-bare one. Every public project that you've ever cloned (hosted on github, for example) is a bare repository on the other end.
    • Derek Mahar
      Derek Mahar about 13 years
      Jefromi, I was correcting AeroCross' point, "so if I clone the bare repo, I won't have a "working tree"", so it is a kind of conversion. And not every public project must be a bare repository. It's just the typical choice because a bare repository is more space efficient since it has no working tree (it's as space efficient as any repository that has no working tree, though).
    • Cascabel
      Cascabel about 13 years
      @Derek: But the point is that, as soon as it finds the .git directory, fetching is wholly unaware of whether the remote is bare or not. It doesn't convert. It just fetches what it needs from the remote, and puts it where it should go. There's nothing to convert. That's what I was trying to emphasize to the OP. And I'm well aware that public projects don't have to be bare, but because people aren't stupid, they essentially all are. I think I made an acceptable generalization.
    • Derek Mahar
      Derek Mahar about 13 years
      Jefromi, I used the term conversion as a metaphor to help AeroCross understand that Git can clone a bare repository. I understand that the repository itself (the contents of .git) does not undergo any conversion unless you count packing free objects for efficiency as a structural conversion. Certainly, Git does not convert the commit and other repository objects during cloning.
    • Exectron
      Exectron about 10 years
      See Push to non-bare repository which gives another excellent explanation of bare repository usage.
    • longbkit
      longbkit about 6 years
      Please see this article, very well explanation: I use a working directory created with git init or git clone when I want to add, edit and delete files in myproject locally on my dev machine. When I am ready, I share my local changes with a git push to a bare repository myproject.git (usually on a remote server like github.com) so other developers can access my local changes. [saintsjd.com/2011/01/what-is-a-bare-git-repository/]
    • John
      John almost 4 years
  • AeroCross
    AeroCross about 13 years
    So that means that I can add branches, tags, etc. to the bare repository then pull from the bare to the non-bare / production repository?
  • AeroCross
    AeroCross about 13 years
    So the bare repository is the best / recommended way to work with several people with no access to THEIR repositories? (Kinda like SVN?)
  • Derek Mahar
    Derek Mahar about 13 years
    AeroCross, I'd say a bare repository is a good choice for that scenario.
  • AeroCross
    AeroCross about 13 years
    I think this is the most detailed answer I can find around. IMO, this is the most significant difference between the bare and non-bare repository, and the answer clears up perfectly the working scheme I'm using. Thanks a lot!
  • Derek Mahar
    Derek Mahar about 13 years
    mipadi, a non-bare repository may not have a checked-out tree. This is the case if you create a non-bare repository with git clone --no-checkout. In this case, the non-bare repository has a location for the workspace, but Git doesn't checkout any files into that workspace.
  • Derek Mahar
    Derek Mahar about 13 years
    Yes, I agree that this is arguably the most significant difference between bare and non-bare Git repositories. The fact that a non-bare repository has a workspace, but a bare repository does not is an important difference, but git clone --no-checkout can create a non-bare repository with no workspace files, too.
  • mipadi
    mipadi about 13 years
    A non-bare repository doesn't necessarily have a default remote "origin", either.
  • Derek Mahar
    Derek Mahar about 13 years
    mipadi, how do yo create such a repository using git clone? As far as I understand, unless you specify --bare, git clone always creates the default remote origin. I agree, however, that after you clone a repository, you can delete the remote origin in the clone.
  • mipadi
    mipadi about 13 years
    You can create a Git repository simply with git init, which will create a non-bare repo with no remote specified.
  • Derek Mahar
    Derek Mahar about 13 years
    mipadi, this is true, but it's also not a clone.
  • Noufal Ibrahim
    Noufal Ibrahim over 12 years
    This is incorrect. A repository will have a default origin if it has been cloneed. If it has been inited locally, it will not have such an origin. This has nothing to do with whether it is bare or not.
  • Derek Mahar
    Derek Mahar over 12 years
    Noufal, this is what mipadi stated a few comments before yours. I stated in a comment to mipadi's answer that you can create a non-bare repository without a checked-out working tree and both you and mipadi pointed out that you can create a non-bare repository without an origin. So what, then, is a key difference between a bare and non-bare repository?
  • Jyotsna Saroha
    Jyotsna Saroha almost 10 years
    Great explanation of bare and non-bare repository @Derek Mahar.
  • mcepl
    mcepl over 9 years
    Now the question is how to change a bare repo into non-bare (e.g., because the original bare repo was a mirror of a remote hg repo and by cloning I would loose all information in .git/hg)?
  • Novice C
    Novice C almost 8 years
    @DerekMahar What do you mean by default remote origin? As stated git init is non-bare and obviously has no origin (same for --bare). I would think that all cloning has an origin. Shouldn't you be checking for the origin with git remote show origin? git clone --bare <repo> clones the repo as a bare repo, meaning it is the .git directory and good notation would be instead git clone --bare <repo> <repo.git>. If you check a clone, either --bare or not, it has an origin. Bares by default rather do not allow pulling from origin (or anywhere), as stated since they have no working tree.
  • Derek Mahar
    Derek Mahar almost 8 years
    @NoviceC A default remote origin is a reference in the repository to the clone source. According to my example (this may have changed in later versions of Git), git clone --bare does not create a default remote origin.
  • Derek Mahar
    Derek Mahar almost 8 years
    Anyway, I'm not sure why the OP accepted this answer. I was trying to provide another difference between bare and non-bare repositories. @mipadi made a good point that a new Git repository created with git init also doesn't have default remote origin. The question didn't require that the bare repository be created only with git clone.
  • Enlico
    Enlico over 5 years
    @DerekMahar, if I create a repo via git clone --bare originalrepo barerepo, and then issue git remote -v while in barerepo directory, I obtain origin /full/path/of/orignalrepo (fetch) and origin /full/path/of/orignalrepo (push); so I'd say barerepo has got the origin remote. Could you elaborate on this? Maybe it's about git version?
  • Enlico
    Enlico over 5 years
    @DerekMahar, oh, btw, when I do git clone --bare originalrepo barerepo the output on stdout is Cloning into bare repository 'barerepo'... and not Initialized empty Git repository in /full/path/of/barerepo/.
  • aderchox
    aderchox almost 4 years
    I thought "n commits ahead" message was related to branches (i.e. refs) and not related to working trees.
  • sehe
    sehe almost 4 years
    @aderchox Yes, Nothing here contradicts that?
  • aderchox
    aderchox almost 4 years
    I mean if a developer makes a push to the remote repository, then all other contributors will be out of sync anyways, whether the remote is a bare or non-bare repository. Maybe I don't quite understand the meaning of "sync" in your answer.
  • sehe
    sehe almost 4 years
    @aderchox If the remote repo isn't bare, it would cause the worktree to get out of sync with a checked out HEAD as well. This is why it wouldn't be allowed, and thus the advantage of having a bare repo (basically, just don't have a worktree)
  • crazyTech
    crazyTech almost 3 years
    Really Good point you bring up. Would it be correct to say "A Nonbare git repository has a supplemental workspace directory tree( but A bare git repository does Not )" ?
  • Mugen
    Mugen over 2 years
    Can't multiple contributors push their work anyway? There's no need for a bare repository. Anyway with a normal repository as well lots of people can work parallely.
  • qneill
    qneill over 2 years
    The "non-bare" repo also contains the staging area stackoverflow.com/questions/49228209/… needed for ongoing development
  • Clomp
    Clomp about 2 years
    Note: The BitFlop link no longer exists in 2022. That domain is up for sale. However, the Atlassian Bitbucket tutorial is still a useful link!
  • Clomp
    Clomp about 2 years
    That makes sense, as the developer's workstation would have a non-bare repository & changes are git pushed into a bare repository on a server.