3

The docs state

--bare

Create a bare repository. If GIT_DIR environment is not set, it is set to the current working directory.

and

--shared[=(false|true|umask|group|all|world|everybody|0xxx)]

Specify that the Git repository is to be shared amongst several users. This allows users belonging to the same group to push into that repository. When specified, the config variable "core.sharedRepository" is set so that files and directories under $GIT_DIR are created with the requested permissions. When not specified, Git will use permissions reported by umask(2).

The option can have the following values, defaulting to group if no value is given: ...

I always thought

  • If I work alone, I can just work in a directory / project without a remote (no bare repo needed)
  • If I share my work I just use Github or something similar or just create my own remote using "--bare" option.

Why do I need anything else? What does "shared" mean? (For the "bare" option see also this question). And I just tested that git init --shared=all is possible and thus independent of --bare. (Which was a surprise after reading this question)

Christoph
  • 6,841
  • 4
  • 37
  • 89

2 Answers2

4

Like the link you mentioned, the two aren't mutually exclusive. --shared is used mainly for managing permissions, and --bare is to create a repo without a working directory, and it's used for sharing. This link was helpful for me: https://serverfault.com/a/113688

saxo
  • 91
  • 1
  • 5
2

As saxo said, these two options can (and sometimes do) work in tandem:

  • --bare makes a bare repository, i.e., a repository with no working tree.

  • --shared=mode makes sure that Git uses Unix-style permissions on its own internal files according to the mode argument. This is not likely to work on anything that is not a Unix-like system, but since Linux is a Unix-like system, it works well on Linux servers.

A bare repository—one with no working tree—cannot have any work done in it. This makes it an ideal recipient for work done elsewhere. That work-done-elsewhere arrives at the server computer via git push.

A non-bare repository can have work done in it. Suppose someone has logged on to the server, and is performing ongoing work in the non-bare repository. Suddenly, someone on some other computer runs git push server branch. This is a request that the server accept new commits and update its (the server's) branch named branch. But the person who is working on the server is in the middle of making updates to that same branch. How will Git reconcile the incoming updates with the logged-in-on-the-server-user's updates? The answer is: It won't. The server Git will refuse the incoming update, because some user is potentially doing work on the server.

Since a bare repository has no working tree, it is impossible to do any work in it. Therefore, no one is working on this bare repository on the server. Therefore it is safe to accept an incoming push. Conclusion: non-bare = not-safe; bare = safe. A --bare clone, on a server, can accept pushes. Hence, server clones are normally bare.

The shared stuff is much more complicated. Given that you have a Linux server with a bare clone, we now ask: Who has access to this Linux server? How do they log in to the server? Does this affect their ability to use git push? The answers here vary, hugely. For instance, the servers that GitHub run don't allow users to log in at all, but do allow, via specialized tricks, ssh push access, as long as the users push as a pseudo-user named git. This method bypasses all the normal Linux security stuff, and the --shared mode stuff becomes irrelevant.

Other systems, however, do allow users to ssh in. Some users have full access as themselves (so that they can use sudo and/or do other administrative tasks directly on the server). Other users may have more limited access, but still as themselves. They "log in" on the server and have a user ID, and with that, user and group IDs and accompanying permissions.

The Linux permissions model allows Git to work with the Linux group-permissions model, provided that the Git repository itself contain group-writable directories. Since Git creates new directories on its own (during, e.g., git push operations), these newly-created directories must have the correct permissions—specifically, group-write permission (and correct group ownership, which is managed separately, not by Git). To make this happen automatically, the adminstrator should create this repository with --shared=group or similar.

torek
  • 448,244
  • 59
  • 642
  • 775
  • Ok, thanks again for the comprehensive and comprehensible answer. Our server is a windows machine - thus `--shared` most likely does nothing. Good to know! – Christoph Jul 27 '21 at 07:35