TL;DR: you may want to configure the shared Git to have receive.denyCurrentBranch
set to updateInstead
. Be sure you know precisely what this means, before doing it! It's more likely that you should configure the shared repository as a bare repository. See also What are the consequences of using receive.denyCurrentBranch in Git?
Long-ish
git init samplerepo
creates a new, empty directory named samplerepo
, then creates a new empty repository within that directory, so that samplerepo
is the work-tree for the new empty repository. This new empty repository has no commits and therefore has no branches (yet). The samplerepo
directory will contain just one sub-directory, .git
, holding the repository proper.
Having created this empty repository, you then cloned it. The cloning process will give you a warning about having cloned an empty repository, because various things tend to be a little weird when working with empty repositories. In any case this clone also has no branches, because a branch name like master
can only exist by containing the hash ID of some existing, valid commit. The empty repository has no commits.
Despite the lack of branches, the empty repository is still on a branch. It's just on a branch that does not exist. This is where the weirdness comes in.
Next, you created a file in your work-tree in the clone, used git add
to copy the file into the index for this clone, and ran git commit
. This created the very first commit in the clone, which is now non-empty. Creating this commit allowed the branch master
to come into existence, which it did. (You could now create an infinite number of additional branch names, if you like: all must, necessarily, identify this one commit that exists.)
Finally, you told your Git to contact another Git on the shared area, //networkdrive/myrepo/samplegitrepo
.1 Your Git gave to this other Git this one commit that you have made, which that Git stored in that repository—the one on the shared drive. Then your Git asked that Git to create or update its branch name master
to identify the one commit. It did so.
Creating the commit in the other Git had no effect on that Git's work-tree. This is the normal behavior of a Git repository: putting new commits into it via git push
does not affect its work-tree. In fact, in general, putting new commits into it, into the branch that it has checked out, is normally denied entirely. The reason it was allowed here is that the branch that it had checked out—its master
—did not exist, for the same reason that your clone's master
did not exist initially.
Now that the branch does exist, future attempts to push to master
will be rejected due to receive.denyCurrentBranch
being unset, which results in the same behavior as if you set it to true
. There is a lot of discussion in the various answers to What are the consequences of using receive.denyCurrentBranch in Git? You should read it.
1More typically, you would contact a whole separate host via some https://
or ssh://
URL. The other host would then have a way of authenticating you and deciding whether to give you access to the Git repository over there. In this case, your own Git fires up a second Git instance to work in the shared drive. That allows Git to keep working as if you're talking to another machine, even though it's just talking to another copy of itself running over in the shared drive. Your OS takes care of authentication automatically, through the shared drive.
This is where the --shared
stuff becomes important, if you plan to let other users on other machine let their OS take care of the sharing. The Linux-oriented Git --shared=true
or --shared=group
setting—that's what --shared
defaults to—depends on Linux-style group permissions. You're showing various Windows-ish paths, and Windows permissions are typically very different from Linux's, so this may not accomplish what you want. I don't "do" Windows, so don't know how to accomplish what you want, but it's worth some attention.